Migrate from Yarn 1 to pnpm (#10465)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Eric Bailey <git@esb.lol>
This commit is contained in:
Samuel Newman
2026-05-18 17:51:04 +01:00
committed by GitHub
parent b7c2c2f183
commit ff731849b0
87 changed files with 20230 additions and 18252 deletions
@@ -1,7 +1,7 @@
diff --git a/node_modules/@discord/bottom-sheet/src/hooks/useStableCallback.ts b/node_modules/@discord/bottom-sheet/src/hooks/useStableCallback.ts
index 1c788ab..d30f330 100644
--- a/node_modules/@discord/bottom-sheet/src/hooks/useStableCallback.ts
+++ b/node_modules/@discord/bottom-sheet/src/hooks/useStableCallback.ts
diff --git a/src/hooks/useStableCallback.ts b/src/hooks/useStableCallback.ts
index 1c788ab72351c21c5aea178d7b416741aa940e1f..d30f330ab1f082ea0477c19e2fa05b7a0b1a3e0d 100644
--- a/src/hooks/useStableCallback.ts
+++ b/src/hooks/useStableCallback.ts
@@ -6,7 +6,7 @@ type Callback = (...args: any[]) => any;
* https://gist.github.com/JakeCoxon/c7ebf6e6496f8468226fd36b596e1985
*/
@@ -1,7 +1,7 @@
diff --git a/node_modules/@sentry/react-native/dist/js/tools/sentryMetroSerializer.js b/node_modules/@sentry/react-native/dist/js/tools/sentryMetroSerializer.js
index d7f2350..e9c0368 100644
--- a/node_modules/@sentry/react-native/dist/js/tools/sentryMetroSerializer.js
+++ b/node_modules/@sentry/react-native/dist/js/tools/sentryMetroSerializer.js
diff --git a/dist/js/tools/sentryMetroSerializer.js b/dist/js/tools/sentryMetroSerializer.js
index d7f2350196fc008f9f1ce530e224fe3d052347e9..4ce7b6614e38c8af747ebcf166dba556affea3de 100644
--- a/dist/js/tools/sentryMetroSerializer.js
+++ b/dist/js/tools/sentryMetroSerializer.js
@@ -12,12 +12,9 @@ exports.createSentryMetroSerializer = exports.unstable_beforeAssetSerializationP
const crypto = require("crypto");
const utils_1 = require("./utils");
@@ -18,10 +18,10 @@ index d7f2350..e9c0368 100644
}
const DEBUG_ID_PLACE_HOLDER = '__debug_id_place_holder__';
const DEBUG_ID_MODULE_PATH = '__debugid__';
diff --git a/node_modules/@sentry/react-native/scripts/expo-upload-sourcemaps.js b/node_modules/@sentry/react-native/scripts/expo-upload-sourcemaps.js
index b3783b5..d5e3e45 100755
--- a/node_modules/@sentry/react-native/scripts/expo-upload-sourcemaps.js
+++ b/node_modules/@sentry/react-native/scripts/expo-upload-sourcemaps.js
diff --git a/scripts/expo-upload-sourcemaps.js b/scripts/expo-upload-sourcemaps.js
index b3783b572171482778d31a96b8d6ebadbcc8783b..d5e3e45477c07b5419285237372d99ddd83c56a6 100755
--- a/scripts/expo-upload-sourcemaps.js
+++ b/scripts/expo-upload-sourcemaps.js
@@ -218,7 +218,7 @@ for (const [assetGroupName, assets] of Object.entries(groupedAssets)) {
const isHermes = assets.find(asset => asset.endsWith('.hbc'));
-16
View File
@@ -1,16 +0,0 @@
diff --git a/node_modules/expo-font/ios/FontLoaderModule.swift b/node_modules/expo-font/ios/FontLoaderModule.swift
index 183480f..7b64f6e 100644
--- a/node_modules/expo-font/ios/FontLoaderModule.swift
+++ b/node_modules/expo-font/ios/FontLoaderModule.swift
@@ -2,10 +2,9 @@ import ExpoModulesCore
public final class FontLoaderModule: Module {
// could be a Set, but to be able to pass to JS we keep it as an array
- private var registeredFonts: [String]
+ private lazy var registeredFonts: [String] = queryCustomNativeFonts()
public required init(appContext: AppContext) {
- self.registeredFonts = queryCustomNativeFonts()
super.init(appContext: appContext)
}
@@ -1,7 +1,7 @@
diff --git a/node_modules/expo-glass-effect/ios/GlassContainer.swift b/node_modules/expo-glass-effect/ios/GlassContainer.swift
index 61fb67c..b2d111e 100644
--- a/node_modules/expo-glass-effect/ios/GlassContainer.swift
+++ b/node_modules/expo-glass-effect/ios/GlassContainer.swift
diff --git a/ios/GlassContainer.swift b/ios/GlassContainer.swift
index 61fb67cdfa2022f57524ddde05096067055e9ee6..b2d111ef8a724b8e7d4404f3d40efce3bd6fbb6d 100644
--- a/ios/GlassContainer.swift
+++ b/ios/GlassContainer.swift
@@ -1,6 +1,7 @@
// Copyright 2022-present 650 Industries. All rights reserved.
@@ -32,10 +32,10 @@ index 61fb67c..b2d111e 100644
childComponentView.removeFromSuperview()
}
}
diff --git a/node_modules/expo-glass-effect/ios/GlassView.swift b/node_modules/expo-glass-effect/ios/GlassView.swift
index 35cd8f3..9587306 100644
--- a/node_modules/expo-glass-effect/ios/GlassView.swift
+++ b/node_modules/expo-glass-effect/ios/GlassView.swift
diff --git a/ios/GlassView.swift b/ios/GlassView.swift
index 35cd8f320009a9e28fdbb2f55cc409734ba98f40..9587306b6fac3455ab27a5289eb62a711aa50c03 100644
--- a/ios/GlassView.swift
+++ b/ios/GlassView.swift
@@ -271,11 +271,19 @@ public final class GlassView: ExpoView {
#endif
}
-13
View File
@@ -1,13 +0,0 @@
diff --git a/node_modules/expo-haptics/android/src/main/java/expo/modules/haptics/HapticsModule.kt b/node_modules/expo-haptics/android/src/main/java/expo/modules/haptics/HapticsModule.kt
index 1520465..6ea988a 100644
--- a/node_modules/expo-haptics/android/src/main/java/expo/modules/haptics/HapticsModule.kt
+++ b/node_modules/expo-haptics/android/src/main/java/expo/modules/haptics/HapticsModule.kt
@@ -42,7 +42,7 @@ class HapticsModule : Module() {
private fun vibrate(type: HapticsVibrationType) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- vibrator.vibrate(VibrationEffect.createWaveform(type.timings, type.amplitudes, -1))
+ vibrator.vibrate(VibrationEffect.createWaveform(type.oldSDKPattern, intArrayOf(0, 100), -1))
} else {
@Suppress("DEPRECATION")
vibrator.vibrate(type.oldSDKPattern, -1)
+13
View File
@@ -0,0 +1,13 @@
diff --git a/android/src/main/java/expo/modules/haptics/HapticsModule.kt b/android/src/main/java/expo/modules/haptics/HapticsModule.kt
index 6102727daafe198ac1170fdef8aea74df0b740d2..bfd4e6d2e730575062394e302c37e00ade20e1ce 100644
--- a/android/src/main/java/expo/modules/haptics/HapticsModule.kt
+++ b/android/src/main/java/expo/modules/haptics/HapticsModule.kt
@@ -48,7 +48,7 @@ class HapticsModule : Module() {
private fun vibrate(type: HapticsVibrationType) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- vibrator.vibrate(VibrationEffect.createWaveform(type.timings, type.amplitudes, -1))
+ vibrator.vibrate(VibrationEffect.createWaveform(type.oldSDKPattern, intArrayOf(0, 100), -1))
} else {
@Suppress("DEPRECATION")
vibrator.vibrate(type.oldSDKPattern, -1)
@@ -1,7 +1,7 @@
diff --git a/node_modules/expo-image-picker/ios/MediaHandler.swift b/node_modules/expo-image-picker/ios/MediaHandler.swift
index 6e4fbe1..e334abb 100644
--- a/node_modules/expo-image-picker/ios/MediaHandler.swift
+++ b/node_modules/expo-image-picker/ios/MediaHandler.swift
diff --git a/ios/MediaHandler.swift b/ios/MediaHandler.swift
index 6e4fbe1b3921173a1cc4e6eff626b0749e8bab14..e334abb680a8965acb1f6bbdfbc1325ad35edf3a 100644
--- a/ios/MediaHandler.swift
+++ b/ios/MediaHandler.swift
@@ -310,10 +310,12 @@ internal struct MediaHandler {
let fileExtension = getFileExtension(from: originalFilename)
let destinationUrl = try generateUrl(withFileExtension: fileExtension)
@@ -0,0 +1,5 @@
# `expo-image-picker` patch
Patches this issue: https://github.com/expo/expo/issues/39937
Source: https://github.com/expo/expo/issues/39937#issuecomment-3342082239
@@ -1,7 +1,7 @@
diff --git a/node_modules/expo-image/build/Image.types.d.ts b/node_modules/expo-image/build/Image.types.d.ts
index 022ae48..416504f 100644
--- a/node_modules/expo-image/build/Image.types.d.ts
+++ b/node_modules/expo-image/build/Image.types.d.ts
diff --git a/build/Image.types.d.ts b/build/Image.types.d.ts
index 022ae487e65ae9d624f8a4be262b01944928f250..416504fe18ecd00fdc713faca23485fb292caf2c 100644
--- a/build/Image.types.d.ts
+++ b/build/Image.types.d.ts
@@ -152,6 +152,16 @@ export interface ImageProps extends Omit<ViewProps, 'style' | 'children'> {
* @default 'normal'
*/
@@ -19,10 +19,10 @@ index 022ae48..416504f 100644
/**
* Determines whether to cache the image and where: on the disk, in the memory or both.
*
diff --git a/node_modules/expo-image/src/ExpoImage.web.tsx b/node_modules/expo-image/src/ExpoImage.web.tsx
index 2a49ff0..1c3de93 100644
--- a/node_modules/expo-image/src/ExpoImage.web.tsx
+++ b/node_modules/expo-image/src/ExpoImage.web.tsx
diff --git a/src/ExpoImage.web.tsx b/src/ExpoImage.web.tsx
index 2a49ff00649b374b86fa780653a4b0d6f13a4a57..1c3de93ef280bf6f3c27bed34c794b8ff59e3db3 100644
--- a/src/ExpoImage.web.tsx
+++ b/src/ExpoImage.web.tsx
@@ -70,6 +70,7 @@ export default function ExpoImage({
onLoadEnd,
onDisplay,
@@ -47,10 +47,10 @@ index 2a49ff0..1c3de93 100644
contentPosition={selectedSource ? contentPosition : { top: '50%', left: '50%' }}
hashPlaceholderContentPosition={contentPosition}
hashPlaceholderStyle={imageHashStyle}
diff --git a/node_modules/expo-image/src/Image.types.ts b/node_modules/expo-image/src/Image.types.ts
index 9dec0e7..61c1621 100644
--- a/node_modules/expo-image/src/Image.types.ts
+++ b/node_modules/expo-image/src/Image.types.ts
diff --git a/src/Image.types.ts b/src/Image.types.ts
index 9dec0e7aee61dfaa73a3cfa535d08259c9dad209..61c162114977dff35b633ac6b1f3d59e373bbbfe 100644
--- a/src/Image.types.ts
+++ b/src/Image.types.ts
@@ -178,6 +178,17 @@ export interface ImageProps extends Omit<ViewProps, 'style' | 'children'> {
*/
priority?: 'low' | 'normal' | 'high' | null;
@@ -69,10 +69,10 @@ index 9dec0e7..61c1621 100644
/**
* Determines whether to cache the image and where: on the disk, in the memory or both.
*
diff --git a/node_modules/expo-image/src/web/ImageWrapper.tsx b/node_modules/expo-image/src/web/ImageWrapper.tsx
index e8f891d..89a5cb1 100644
--- a/node_modules/expo-image/src/web/ImageWrapper.tsx
+++ b/node_modules/expo-image/src/web/ImageWrapper.tsx
diff --git a/src/web/ImageWrapper.tsx b/src/web/ImageWrapper.tsx
index e8f891d525892f8d3668e34cf96cefccfbfc49f6..89a5cb1e3a8574fc3bd1d0361895a610e3165dfb 100644
--- a/src/web/ImageWrapper.tsx
+++ b/src/web/ImageWrapper.tsx
@@ -30,6 +30,7 @@ const ImageWrapper = React.forwardRef(
contentPosition,
hashPlaceholderContentPosition,
@@ -89,10 +89,10 @@ index e8f891d..89a5cb1 100644
{...getImageWrapperEventHandler(events, sourceWithHeaders)}
{...getImgPropsFromSource(source)}
{...props}
diff --git a/node_modules/expo-image/src/web/ImageWrapper.types.ts b/node_modules/expo-image/src/web/ImageWrapper.types.ts
index 19bbe2f..179837f 100644
--- a/node_modules/expo-image/src/web/ImageWrapper.types.ts
+++ b/node_modules/expo-image/src/web/ImageWrapper.types.ts
diff --git a/src/web/ImageWrapper.types.ts b/src/web/ImageWrapper.types.ts
index 19bbe2f15999124cda0ca7c81b3ebcf289f522f8..179837f803a3d315c85075895f4191631b37eda7 100644
--- a/src/web/ImageWrapper.types.ts
+++ b/src/web/ImageWrapper.types.ts
@@ -29,6 +29,7 @@ export type ImageWrapperProps = {
contentPosition?: ImageContentPositionObject;
hashPlaceholderContentPosition?: ImageContentPositionObject;
+3
View File
@@ -0,0 +1,3 @@
## Expo Image
Patches in https://github.com/expo/expo/pull/41442
-13
View File
@@ -1,13 +0,0 @@
diff --git a/node_modules/expo-media-library/android/src/main/java/expo/modules/medialibrary/MediaLibraryModule.kt b/node_modules/expo-media-library/android/src/main/java/expo/modules/medialibrary/MediaLibraryModule.kt
index 2dc1db2..ee844e8 100644
--- a/node_modules/expo-media-library/android/src/main/java/expo/modules/medialibrary/MediaLibraryModule.kt
+++ b/node_modules/expo-media-library/android/src/main/java/expo/modules/medialibrary/MediaLibraryModule.kt
@@ -105,7 +105,7 @@ class MediaLibraryModule : Module() {
}
AsyncFunction("createAssetAsync") Coroutine { localUri: String, albumId: String? ->
- requireSystemPermissions()
+ // requireSystemPermissions()
return@Coroutine createAssetWithAlbumId(context, localUri, true, albumId)
}
+13
View File
@@ -0,0 +1,13 @@
diff --git a/android/src/main/java/expo/modules/medialibrary/MediaLibraryModule.kt b/android/src/main/java/expo/modules/medialibrary/MediaLibraryModule.kt
index 97c19ff07a49dc80adce7f100eb205b2045dc115..a9a520617eb74caddbbd9cbd15635f113017ab65 100644
--- a/android/src/main/java/expo/modules/medialibrary/MediaLibraryModule.kt
+++ b/android/src/main/java/expo/modules/medialibrary/MediaLibraryModule.kt
@@ -109,7 +109,7 @@ class MediaLibraryModule : Module() {
}
AsyncFunction("createAssetAsync") Coroutine { localUri: String, albumId: String? ->
- requireSystemPermissions()
+ // requireSystemPermissions()
return@Coroutine createAssetWithAlbumId(context, localUri, true, albumId)
}
@@ -0,0 +1 @@
Unclear why this is needed
-15
View File
@@ -1,15 +0,0 @@
diff --git a/node_modules/expo-modules-core/android/src/main/java/expo/modules/kotlin/devtools/ExpoNetworkInspectOkHttpInterceptors.kt b/node_modules/expo-modules-core/android/src/main/java/expo/modules/kotlin/devtools/ExpoNetworkInspectOkHttpInterceptors.kt
index 47c4d15..afe138d 100644
--- a/node_modules/expo-modules-core/android/src/main/java/expo/modules/kotlin/devtools/ExpoNetworkInspectOkHttpInterceptors.kt
+++ b/node_modules/expo-modules-core/android/src/main/java/expo/modules/kotlin/devtools/ExpoNetworkInspectOkHttpInterceptors.kt
@@ -125,6 +125,10 @@ internal fun peekResponseBody(
}
internal fun shouldParseBody(response: Response): Boolean {
+ if (response.request.url.encodedPath == "/bitdrift_public.protobuf.client.v1.ApiService/Mux") {
+ return false
+ }
+
// Check for Content-Type
val skipContentTypes = listOf(
"text/event-stream", // Server Sent Events
+15
View File
@@ -0,0 +1,15 @@
diff --git a/android/src/main/java/expo/modules/kotlin/devtools/ExpoNetworkInspectOkHttpInterceptors.kt b/android/src/main/java/expo/modules/kotlin/devtools/ExpoNetworkInspectOkHttpInterceptors.kt
index 47c4d15f6b10bbd77858cfff425cda9a618735b9..afe138d22d566244482498a7be0e14b8454eab96 100644
--- a/android/src/main/java/expo/modules/kotlin/devtools/ExpoNetworkInspectOkHttpInterceptors.kt
+++ b/android/src/main/java/expo/modules/kotlin/devtools/ExpoNetworkInspectOkHttpInterceptors.kt
@@ -125,6 +125,10 @@ internal fun peekResponseBody(
}
internal fun shouldParseBody(response: Response): Boolean {
+ if (response.request.url.encodedPath == "/bitdrift_public.protobuf.client.v1.ApiService/Mux") {
+ return false
+ }
+
// Check for Content-Type
val skipContentTypes = listOf(
"text/event-stream", // Server Sent Events
@@ -1,7 +1,7 @@
diff --git a/node_modules/expo-notifications/android/build.gradle b/node_modules/expo-notifications/android/build.gradle
index bc479ee..1ebfa00 100644
--- a/node_modules/expo-notifications/android/build.gradle
+++ b/node_modules/expo-notifications/android/build.gradle
diff --git a/android/build.gradle b/android/build.gradle
index 7db47bdf190b0790c7bf867fbcfeb594005861be..0f868153edd6ec557730531f61dba7bf26a71742 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -42,6 +42,7 @@ dependencies {
implementation 'com.google.firebase:firebase-messaging:24.0.1'
@@ -10,10 +10,10 @@ index bc479ee..1ebfa00 100644
if (project.findProject(':expo-modules-test-core')) {
testImplementation project(':expo-modules-test-core')
diff --git a/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/interfaces/INotificationContent.kt b/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/interfaces/INotificationContent.kt
index 7b99e6c..45a450d 100644
--- a/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/interfaces/INotificationContent.kt
+++ b/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/interfaces/INotificationContent.kt
diff --git a/android/src/main/java/expo/modules/notifications/notifications/interfaces/INotificationContent.kt b/android/src/main/java/expo/modules/notifications/notifications/interfaces/INotificationContent.kt
index 7b99e6cf8ee1b0de07a79fe4486c49ff25e489c6..45a450da1c5fff13461b77d3a7b20d0217035687 100644
--- a/android/src/main/java/expo/modules/notifications/notifications/interfaces/INotificationContent.kt
+++ b/android/src/main/java/expo/modules/notifications/notifications/interfaces/INotificationContent.kt
@@ -15,6 +15,7 @@ import org.json.JSONObject
* This interface exists to provide a common API for both classes.
* */
@@ -22,10 +22,10 @@ index 7b99e6c..45a450d 100644
val title: String?
val text: String?
val subText: String?
diff --git a/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/model/NotificationContent.java b/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/model/NotificationContent.java
index 191b64e..fe8b3c5 100644
--- a/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/model/NotificationContent.java
+++ b/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/model/NotificationContent.java
diff --git a/android/src/main/java/expo/modules/notifications/notifications/model/NotificationContent.java b/android/src/main/java/expo/modules/notifications/notifications/model/NotificationContent.java
index 191b64e101c03eeec37920c2d6582bfd50d8b902..fe8b3c51d6f7c661484467f0d820836145824676 100644
--- a/android/src/main/java/expo/modules/notifications/notifications/model/NotificationContent.java
+++ b/android/src/main/java/expo/modules/notifications/notifications/model/NotificationContent.java
@@ -35,6 +35,7 @@ import kotlin.coroutines.Continuation;
* Refactoring this class may require a migration strategy for the data stored in SharedPreferences.
*/
@@ -82,10 +82,10 @@ index 191b64e..fe8b3c5 100644
public Builder setTitle(String title) {
content.mTitle = title;
return this;
diff --git a/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/model/NotificationData.kt b/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/model/NotificationData.kt
index 3af254c..3c77e9d 100644
--- a/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/model/NotificationData.kt
+++ b/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/model/NotificationData.kt
diff --git a/android/src/main/java/expo/modules/notifications/notifications/model/NotificationData.kt b/android/src/main/java/expo/modules/notifications/notifications/model/NotificationData.kt
index 3af254c6b5fecb8f850c023422db4d80bd4815a5..3c77e9d774f2d8fcfa5d34dc7b088958676cba71 100644
--- a/android/src/main/java/expo/modules/notifications/notifications/model/NotificationData.kt
+++ b/android/src/main/java/expo/modules/notifications/notifications/model/NotificationData.kt
@@ -11,6 +11,9 @@ import org.json.JSONObject
* */
@JvmInline
@@ -96,10 +96,10 @@ index 3af254c..3c77e9d 100644
val title: String?
get() = data["title"]
diff --git a/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/model/RemoteNotificationContent.kt b/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/model/RemoteNotificationContent.kt
index d2cc6cf..6a48ff2 100644
--- a/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/model/RemoteNotificationContent.kt
+++ b/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/model/RemoteNotificationContent.kt
diff --git a/android/src/main/java/expo/modules/notifications/notifications/model/RemoteNotificationContent.kt b/android/src/main/java/expo/modules/notifications/notifications/model/RemoteNotificationContent.kt
index cdbc237948ae9de7e85aeb3902e724c44557453c..6d970066decfa47d68299a5bd8febd953f9c2060 100644
--- a/android/src/main/java/expo/modules/notifications/notifications/model/RemoteNotificationContent.kt
+++ b/android/src/main/java/expo/modules/notifications/notifications/model/RemoteNotificationContent.kt
@@ -31,6 +31,8 @@ class RemoteNotificationContent(private val remoteMessage: RemoteMessage) : INot
return remoteMessage.notification?.imageUrl != null
}
@@ -109,10 +109,10 @@ index d2cc6cf..6a48ff2 100644
override val title = remoteMessage.notification?.title ?: notificationData.title
override val text = remoteMessage.notification?.body ?: notificationData.message
diff --git a/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/presentation/builders/ExpoNotificationBuilder.kt b/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/presentation/builders/ExpoNotificationBuilder.kt
index 98f003f..2f745e8 100644
--- a/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/presentation/builders/ExpoNotificationBuilder.kt
+++ b/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/presentation/builders/ExpoNotificationBuilder.kt
diff --git a/android/src/main/java/expo/modules/notifications/notifications/presentation/builders/ExpoNotificationBuilder.kt b/android/src/main/java/expo/modules/notifications/notifications/presentation/builders/ExpoNotificationBuilder.kt
index 610d3039cefd589647538ad8ba14587d29fab338..3655fc3121ebc0a97820d9653b61a90bd7c34fc2 100644
--- a/android/src/main/java/expo/modules/notifications/notifications/presentation/builders/ExpoNotificationBuilder.kt
+++ b/android/src/main/java/expo/modules/notifications/notifications/presentation/builders/ExpoNotificationBuilder.kt
@@ -101,6 +101,9 @@ open class ExpoNotificationBuilder(
builder.setOngoing(content.isSticky)
@@ -123,10 +123,10 @@ index 98f003f..2f745e8 100644
builder.setContentTitle(content.title)
builder.setContentText(content.text)
builder.setSubText(content.subText)
diff --git a/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/service/delegates/FirebaseMessagingDelegate.kt b/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/service/delegates/FirebaseMessagingDelegate.kt
index 90ca4ff..9d4cb09 100644
--- a/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/service/delegates/FirebaseMessagingDelegate.kt
+++ b/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/service/delegates/FirebaseMessagingDelegate.kt
diff --git a/android/src/main/java/expo/modules/notifications/service/delegates/FirebaseMessagingDelegate.kt b/android/src/main/java/expo/modules/notifications/service/delegates/FirebaseMessagingDelegate.kt
index 90ca4ff35132b33dcccb80b90d68572506fef603..9d4cb09b35844805d543acff54772380c732c02c 100644
--- a/android/src/main/java/expo/modules/notifications/service/delegates/FirebaseMessagingDelegate.kt
+++ b/android/src/main/java/expo/modules/notifications/service/delegates/FirebaseMessagingDelegate.kt
@@ -3,6 +3,9 @@ package expo.modules.notifications.service.delegates
import android.content.Context
import android.os.Bundle
-136
View File
@@ -1,136 +0,0 @@
diff --git a/node_modules/expo-paste-input/ios/ExpoPasteInputView.swift b/node_modules/expo-paste-input/ios/ExpoPasteInputView.swift
index 2164aec4ec1d..d216db6d2927 100644
--- a/node_modules/expo-paste-input/ios/ExpoPasteInputView.swift
+++ b/node_modules/expo-paste-input/ios/ExpoPasteInputView.swift
@@ -511,14 +511,17 @@ class ExpoPasteInputView: ExpoView {
var attachmentRanges: [NSRange] = []
var mediaPayloads: [MediaPayload] = []
+ // Only track ranges for attachments we successfully extract a real payload
+ // from. Attachments without a payload (e.g. iOS dictation placeholders)
+ // are left alone — sanitizing them would delete characters the system
+ // manages itself, and emitting "unsupported" would raise a spurious error.
attributedText.enumerateAttribute(.attachment, in: NSRange(location: 0, length: attributedText.length), options: []) { value, range, _ in
guard let attachment = value as? NSTextAttachment else {
return
}
- attachmentRanges.append(range)
-
if let payload = self.extractMediaPayload(from: attachment, textView: textView, range: range) {
+ attachmentRanges.append(range)
mediaPayloads.append(payload)
}
}
@@ -529,9 +532,8 @@ class ExpoPasteInputView: ExpoView {
return
}
- attachmentRanges.append(range)
-
if let payload = self.extractMediaPayload(from: adaptiveGlyph) {
+ attachmentRanges.append(range)
mediaPayloads.append(payload)
}
}
@@ -539,17 +541,12 @@ class ExpoPasteInputView: ExpoView {
attachmentRanges = uniqueRanges(attachmentRanges)
- guard !attachmentRanges.isEmpty else {
- return
- }
-
- sanitizeAttachments(in: textView, ranges: attachmentRanges)
-
guard !mediaPayloads.isEmpty else {
- handleUnsupportedPaste()
return
}
+ sanitizeAttachments(in: textView, ranges: attachmentRanges)
+
emitImagesAsync(for: mediaPayloads)
}
@@ -651,6 +648,11 @@ class ExpoPasteInputView: ExpoView {
}
private func extractMediaPayload(from attachment: NSTextAttachment, textView: UITextView, range: NSRange) -> MediaPayload? {
+ // Only accept attachments that carry real image payloads. We intentionally
+ // do not fall back to `image(forBounds:)` or rendering the text view's
+ // hierarchy, because system-inserted attachments (e.g. the iOS dictation
+ // placeholder) draw themselves via those paths and would cause us to
+ // emit a screenshot of the composer as a "pasted image".
if let fileWrapperData = attachment.fileWrapper?.regularFileContents,
let payload = extractMediaPayload(fromData: fileWrapperData) {
return payload
@@ -667,20 +669,6 @@ class ExpoPasteInputView: ExpoView {
return .image(image)
}
- let attachmentBounds = attachment.bounds.size.width > 0 && attachment.bounds.size.height > 0
- ? attachment.bounds
- : CGRect(origin: .zero, size: CGSize(width: 128, height: 128))
-
- if let image = attachment.image(forBounds: attachmentBounds, textContainer: textView.textContainer, characterIndex: range.location),
- image.size.width > 0,
- image.size.height > 0 {
- return .image(image)
- }
-
- if let renderedImage = renderTextAttachment(in: textView, range: range) {
- return .image(renderedImage)
- }
-
return nil
}
@@ -701,47 +689,6 @@ class ExpoPasteInputView: ExpoView {
return .imageData(data)
}
- private func renderTextAttachment(in textView: UITextView, range: NSRange) -> UIImage? {
- let glyphRange = textView.layoutManager.glyphRange(forCharacterRange: range, actualCharacterRange: nil)
- var rect = textView.layoutManager.boundingRect(forGlyphRange: glyphRange, in: textView.textContainer)
-
- rect.origin.x += textView.textContainerInset.left - textView.contentOffset.x
- rect.origin.y += textView.textContainerInset.top - textView.contentOffset.y
- rect = rect.integral
-
- guard rect.width > 1, rect.height > 1 else {
- return nil
- }
-
- let format = UIGraphicsImageRendererFormat.default()
- format.scale = textView.window?.screen.scale ?? UIScreen.main.scale
- format.opaque = false
-
- let image = UIGraphicsImageRenderer(size: rect.size, format: format).image { _ in
- let drawRect = CGRect(
- origin: CGPoint(x: -rect.origin.x, y: -rect.origin.y),
- size: textView.bounds.size
- )
-
- if textView.window != nil {
- textView.drawHierarchy(in: drawRect, afterScreenUpdates: false)
- } else {
- guard let context = UIGraphicsGetCurrentContext() else {
- return
- }
-
- context.translateBy(x: -rect.origin.x, y: -rect.origin.y)
- textView.layer.render(in: context)
- }
- }
-
- guard image.size.width > 0, image.size.height > 0 else {
- return nil
- }
-
- return image
- }
-
@available(iOS 18.0, *)
private func handleAdaptiveImageGlyphInsertion(_ adaptiveGlyph: NSAdaptiveImageGlyph) -> Bool {
guard let payload = extractMediaPayload(from: adaptiveGlyph) else {
-22
View File
@@ -1,22 +0,0 @@
# Expo Paste Input Patch
`expo-paste-input` observes `UITextView.textDidChangeNotification` and treats any
`NSTextAttachment` in the text view's `attributedText` as a pasted image. When
it can't find a real image payload on an attachment, it falls back to
`image(forBounds:)` and, failing that, to a `drawHierarchy` screenshot of the
text view at the attachment's glyph rect.
iOS Dictation inserts its own `NSTextAttachment` (the shimmer/cursor indicator)
into the text view during dictation. Those attachments don't carry real image
data, so the fallbacks would fire — emitting a zoomed-in screenshot of the
composer as if the user had pasted an image at the end of dictation.
This patch:
- Removes the `image(forBounds:)` and `renderTextAttachment` fallbacks in
`extractMediaPayload` so the library only accepts attachments carrying a real
payload (`fileWrapper`, `contents`, or `image`).
- Only sanitizes (deletes) attachment ranges that produced a payload, and
skips the "unsupported" toast when an attachment has no payload. Unknown
system attachments like the dictation placeholder are left alone rather
than being ripped out from under iOS.
@@ -1,7 +1,7 @@
diff --git a/node_modules/expo-updates/ios/EXUpdates/Update/ExpoUpdatesUpdate.swift b/node_modules/expo-updates/ios/EXUpdates/Update/ExpoUpdatesUpdate.swift
index 68086bd..78c7761 100644
--- a/node_modules/expo-updates/ios/EXUpdates/Update/ExpoUpdatesUpdate.swift
+++ b/node_modules/expo-updates/ios/EXUpdates/Update/ExpoUpdatesUpdate.swift
diff --git a/ios/EXUpdates/Update/ExpoUpdatesUpdate.swift b/ios/EXUpdates/Update/ExpoUpdatesUpdate.swift
index 68086bd9963675e71fcc4008df693fed9110cd3a..78c776191ac9071ff0057fd9d045ca1e01011dcf 100644
--- a/ios/EXUpdates/Update/ExpoUpdatesUpdate.swift
+++ b/ios/EXUpdates/Update/ExpoUpdatesUpdate.swift
@@ -78,13 +78,20 @@ public final class ExpoUpdatesUpdate: Update {
status = UpdateStatus.StatusPending
}
@@ -1,71 +0,0 @@
diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h
index e9b330f..5fbb2e0 100644
--- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h
+++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h
@@ -15,5 +15,6 @@
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) RCTDirectEventBlock onRefresh;
@property (nonatomic, weak) UIScrollView *scrollView;
+@property (nonatomic, copy) UIColor *customTintColor;
@end
diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m
index 53bfd04..e2e0c9f 100644
--- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m
+++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m
@@ -23,6 +23,7 @@ @implementation RCTRefreshControl {
UIColor *_titleColor;
CGFloat _progressViewOffset;
BOOL _hasMovedToWindow;
+ UIColor *_customTintColor;
}
- (instancetype)init
@@ -58,6 +59,12 @@ - (void)layoutSubviews
_isInitialRender = false;
}
+- (void)didMoveToSuperview
+{
+ [super didMoveToSuperview];
+ [self setTintColor:_customTintColor];
+}
+
- (void)didMoveToWindow
{
[super didMoveToWindow];
@@ -221,4 +228,16 @@ - (void)refreshControlValueChanged
}
}
+// Fix for https://github.com/facebook/react-native/issues/43388
+// A bug in iOS 17.4 causes the haptic to not play when refreshing if the tintColor
+// is set before the refresh control gets added to the scrollview. We'll call this
+// function whenever the superview changes. We'll also call it if the value of customTintColor
+// changes.
+- (void)setTintColor:(UIColor *)tintColor
+{
+ if ([self.superview isKindOfClass:[UIScrollView class]] && self.tintColor != tintColor) {
+ [super setTintColor:tintColor];
+ }
+}
+
@end
diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControlManager.m b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControlManager.m
index 40aaf9c..1c60164 100644
--- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControlManager.m
+++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControlManager.m
@@ -22,11 +22,12 @@ - (UIView *)view
RCT_EXPORT_VIEW_PROPERTY(onRefresh, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(refreshing, BOOL)
-RCT_EXPORT_VIEW_PROPERTY(tintColor, UIColor)
RCT_EXPORT_VIEW_PROPERTY(title, NSString)
RCT_EXPORT_VIEW_PROPERTY(titleColor, UIColor)
RCT_EXPORT_VIEW_PROPERTY(progressViewOffset, CGFloat)
+RCT_REMAP_VIEW_PROPERTY(tintColor, customTintColor, UIColor)
+
RCT_EXPORT_METHOD(setNativeRefreshing : (nonnull NSNumber *)viewTag toRefreshing : (BOOL)refreshing)
{
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
@@ -1,67 +0,0 @@
diff --git a/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.h b/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.h
index 914a249..0deac55 100644
--- a/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.h
+++ b/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.h
@@ -19,6 +19,8 @@ NS_ASSUME_NONNULL_BEGIN
*/
@interface RCTPullToRefreshViewComponentView : RCTViewComponentView <RCTCustomPullToRefreshViewProtocol>
+- (void)beginRefreshingProgrammatically;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h
index 5fbb2e0..ec5f58c 100644
--- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h
+++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h
@@ -17,4 +17,6 @@
@property (nonatomic, weak) UIScrollView *scrollView;
@property (nonatomic, copy) UIColor *customTintColor;
+- (void)forwarderBeginRefreshing;
+
@end
diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m
index e2e0c9f..ff1b1ed 100644
--- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m
+++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m
@@ -240,4 +240,38 @@ - (void)setTintColor:(UIColor *)tintColor
}
}
+// This method is used by Bluesky's ExpoScrollForwarder. This allows other React Native
+// libraries to perform a refresh of a scrollview and access the refresh control's onRefresh
+// function.
+- (void)forwarderBeginRefreshing
+{
+ _refreshingProgrammatically = NO;
+
+ [self sizeToFit];
+
+ if (!self.scrollView) {
+ return;
+ }
+
+ UIScrollView *scrollView = (UIScrollView *)self.scrollView;
+
+ [UIView animateWithDuration:0.3
+ delay:0
+ options:UIViewAnimationOptionBeginFromCurrentState
+ animations:^(void) {
+ // Whenever we call this method, the scrollview will always be at a position of
+ // -130 or less. Scrolling back to -65 simulates the default behavior of RCTRefreshControl
+ [scrollView setContentOffset:CGPointMake(0, -65)];
+ }
+ completion:^(__unused BOOL finished) {
+ [super beginRefreshing];
+ [self setCurrentRefreshingState:super.refreshing];
+
+ if (self->_onRefresh) {
+ self->_onRefresh(nil);
+ }
+ }
+ ];
+}
+
@end
@@ -1,16 +0,0 @@
diff --git a/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm b/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm
index d029337..0f63ea3 100644
--- a/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm
+++ b/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm
@@ -1038,6 +1038,11 @@ - (void)_adjustForMaintainVisibleContentPosition
}
}
++ (BOOL)shouldBeRecycled
+{
+ return NO;
+}
+
@end
Class<RCTComponentViewProtocol> RCTScrollViewCls(void)
@@ -1,16 +0,0 @@
diff --git a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.kt b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.kt
index 8b65716..27c97bf 100644
--- a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.kt
+++ b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.kt
@@ -313,8 +313,9 @@ public open class JavaTimerManager(
// We also capture the idleCallbackRunnable to tentatively fix:
// https://github.com/facebook/react-native/issues/44842
currentIdleCallbackRunnable?.cancel()
- currentIdleCallbackRunnable = IdleCallbackRunnable(frameTimeNanos)
- reactApplicationContext.runOnJSQueueThread(currentIdleCallbackRunnable)
+ val idleCallbackRunnable = IdleCallbackRunnable(frameTimeNanos)
+ currentIdleCallbackRunnable = idleCallbackRunnable
+ reactApplicationContext.runOnJSQueueThread(idleCallbackRunnable)
reactChoreographer.postFrameCallback(ReactChoreographer.CallbackType.IDLE_EVENT, this)
}
}
@@ -1,16 +0,0 @@
diff --git a/node_modules/react-native/third-party-podspecs/fmt.podspec b/node_modules/react-native/third-party-podspecs/fmt.podspec
index 2f38990..9b02e48 100644
--- a/node_modules/react-native/third-party-podspecs/fmt.podspec
+++ b/node_modules/react-native/third-party-podspecs/fmt.podspec
@@ -26,4 +26,11 @@ Pod::Spec.new do |spec|
spec.public_header_files = "include/fmt/*.h"
spec.header_mappings_dir = "include"
spec.source_files = ["include/fmt/*.h", "src/format.cc"]
+
+ # TODO: Remove after upgrading React Native past 0.83.x
+ # Fix fmt 11.0.2 consteval build error with Xcode 26.4 (facebook/react-native#55601)
+ # Fixed in RN 0.84+ which bumps fmt to a compatible version.
+ spec.prepare_command = <<~SCRIPT
+ perl -i -pe 's/^# define FMT_USE_CONSTEVAL 1$/# define FMT_USE_CONSTEVAL 0/' include/fmt/base.h
+ SCRIPT
end
@@ -1,516 +0,0 @@
diff --git a/node_modules/react-native-compressor/android/build.gradle b/node_modules/react-native-compressor/android/build.gradle
index 5071139..84bee34 100644
--- a/node_modules/react-native-compressor/android/build.gradle
+++ b/node_modules/react-native-compressor/android/build.gradle
@@ -115,7 +115,6 @@ dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4"
implementation 'org.mp4parser:isoparser:1.9.56'
- implementation 'com.github.banketree:AndroidLame-kotlin:v0.0.1'
implementation 'javazoom:jlayer:1.0.1'
}
diff --git a/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioCompressor.kt b/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioCompressor.kt
deleted file mode 100644
index 9292d3e..0000000
--- a/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioCompressor.kt
+++ /dev/null
@@ -1,264 +0,0 @@
-package com.reactnativecompressor.Audio
-
-
-import android.annotation.SuppressLint
-import com.facebook.react.bridge.Promise
-import com.facebook.react.bridge.ReactApplicationContext
-import com.facebook.react.bridge.ReadableMap
-import com.naman14.androidlame.LameBuilder
-import com.naman14.androidlame.WaveReader
-import com.reactnativecompressor.Utils.MediaCache
-import com.reactnativecompressor.Utils.Utils
-import com.reactnativecompressor.Utils.Utils.addLog
-import javazoom.jl.converter.Converter
-import javazoom.jl.decoder.JavaLayerException
-import java.io.BufferedOutputStream
-import java.io.File
-import java.io.FileNotFoundException
-import java.io.FileOutputStream
-import java.io.IOException
-
-class AudioCompressor {
- companion object {
- val TAG="AudioMain"
- private const val OUTPUT_STREAM_BUFFER = 8192
-
- var outputStream: BufferedOutputStream? = null
- var waveReader: WaveReader? = null
- @JvmStatic
- fun CompressAudio(
- fileUrl: String,
- optionMap: ReadableMap,
- context: ReactApplicationContext,
- promise: Promise,
- ) {
- val realPath = Utils.getRealPath(fileUrl, context)
- var _fileUrl=realPath
- val filePathWithoutFileUri = realPath!!.replace("file://", "")
- try {
- var wavPath=filePathWithoutFileUri;
- var isNonWav:Boolean=false
- if (fileUrl.endsWith(".mp4", ignoreCase = true))
- {
- addLog("mp4 file found")
- val mp3Path= Utils.generateCacheFilePath("mp3", context)
- AudioExtractor().genVideoUsingMuxer(fileUrl, mp3Path, -1, -1, true, false)
- _fileUrl=Utils.slashifyFilePath(mp3Path)
- wavPath= Utils.generateCacheFilePath("wav", context)
- try {
- val converter = Converter()
- converter.convert(mp3Path, wavPath)
- } catch (e: JavaLayerException) {
- addLog("JavaLayerException error"+e.localizedMessage)
- e.printStackTrace();
- }
- isNonWav=true
- }
- else if (!fileUrl.endsWith(".wav", ignoreCase = true))
- {
- addLog("non wav file found")
- wavPath= Utils.generateCacheFilePath("wav", context)
- try {
- val converter = Converter()
- converter.convert(filePathWithoutFileUri, wavPath)
- } catch (e: JavaLayerException) {
- addLog("JavaLayerException error"+e.localizedMessage)
- e.printStackTrace();
- }
- isNonWav=true
- }
-
-
- autoCompressHelper(wavPath,filePathWithoutFileUri, optionMap,context) { mp3Path, finished ->
- if (finished) {
- val returnableFilePath:String="file://$mp3Path"
- addLog("finished: " + returnableFilePath)
- MediaCache.removeCompletedImagePath(fileUrl)
- if(isNonWav)
- {
- File(wavPath).delete()
- }
- promise.resolve(returnableFilePath)
- } else {
- addLog("error: "+mp3Path)
- promise.resolve(_fileUrl)
- }
- }
- } catch (e: Exception) {
- promise.resolve(_fileUrl)
- }
- }
-
- @SuppressLint("WrongConstant")
- private fun autoCompressHelper(
- fileUrl: String,
- actualFileUrl: String,
- optionMap: ReadableMap,
- context: ReactApplicationContext,
- completeCallback: (String, Boolean) -> Unit
- ) {
-
- val options = AudioHelper.fromMap(optionMap)
- val quality = options.quality
-
- var isCompletedCallbackTriggered:Boolean=false
- try {
- var mp3Path = Utils.generateCacheFilePath("mp3", context)
- val input = File(fileUrl)
- val output = File(mp3Path)
-
- val CHUNK_SIZE = 8192
- addLog("Initialising wav reader")
-
- waveReader = WaveReader(input)
-
- try {
- waveReader!!.openWave()
- } catch (e: IOException) {
- e.printStackTrace()
- }
-
- addLog("Intitialising encoder")
-
-
- // for bitrate
- var audioBitrate:Int
- if(options.bitrate != -1)
- {
- audioBitrate= options.bitrate/1000
- }
- else
- {
- audioBitrate=AudioHelper.getDestinationBitrateByQuality(actualFileUrl, quality!!)
- Utils.addLog("dest bitrate: $audioBitrate")
- }
-
- var androidLame = LameBuilder();
- androidLame.setOutBitrate(audioBitrate)
-
- // for channels
- var audioChannels:Int
- if(options.channels != -1){
- audioChannels= options.channels!!
- }
- else
- {
- audioChannels=waveReader!!.channels
- }
- androidLame.setOutChannels(audioChannels)
-
- // for sample rate
- androidLame.setInSampleRate(waveReader!!.sampleRate)
- var audioSampleRate:Int
- if(options.samplerate != -1){
- audioSampleRate= options.samplerate!!
- }
- else
- {
- audioSampleRate=waveReader!!.sampleRate
- }
- androidLame.setOutSampleRate(audioSampleRate)
- val androidLameBuild=androidLame.build()
-
- try {
- outputStream = BufferedOutputStream(FileOutputStream(output), OUTPUT_STREAM_BUFFER)
- } catch (e: FileNotFoundException) {
- e.printStackTrace()
- }
-
- var bytesRead = 0
-
- val buffer_l = ShortArray(CHUNK_SIZE)
- val buffer_r = ShortArray(CHUNK_SIZE)
- val mp3Buf = ByteArray(CHUNK_SIZE)
-
- val channels = waveReader!!.channels
-
- addLog("started encoding")
- while (true) {
- try {
- if (channels == 2) {
-
- bytesRead = waveReader!!.read(buffer_l, buffer_r, CHUNK_SIZE)
- addLog("bytes read=$bytesRead")
-
- if (bytesRead > 0) {
-
- var bytesEncoded = 0
- bytesEncoded = androidLameBuild.encode(buffer_l, buffer_r, bytesRead, mp3Buf)
- addLog("bytes encoded=$bytesEncoded")
-
- if (bytesEncoded > 0) {
- try {
- addLog("writing mp3 buffer to outputstream with $bytesEncoded bytes")
- outputStream!!.write(mp3Buf, 0, bytesEncoded)
- } catch (e: IOException) {
- e.printStackTrace()
- }
-
- }
-
- } else
- break
- } else {
-
- bytesRead = waveReader!!.read(buffer_l, CHUNK_SIZE)
- addLog("bytes read=$bytesRead")
-
- if (bytesRead > 0) {
- var bytesEncoded = 0
-
- bytesEncoded = androidLameBuild.encode(buffer_l, buffer_l, bytesRead, mp3Buf)
- addLog("bytes encoded=$bytesEncoded")
-
- if (bytesEncoded > 0) {
- try {
- addLog("writing mp3 buffer to outputstream with $bytesEncoded bytes")
- outputStream!!.write(mp3Buf, 0, bytesEncoded)
- } catch (e: IOException) {
- e.printStackTrace()
- }
-
- }
-
- } else
- break
- }
-
-
- } catch (e: IOException) {
- e.printStackTrace()
- }
-
- }
-
- addLog("flushing final mp3buffer")
- val outputMp3buf = androidLameBuild.flush(mp3Buf)
- addLog("flushed $outputMp3buf bytes")
- if (outputMp3buf > 0) {
- try {
- addLog("writing final mp3buffer to outputstream")
- outputStream!!.write(mp3Buf, 0, outputMp3buf)
- addLog("closing output stream")
- outputStream!!.close()
- completeCallback(output.absolutePath, true)
- isCompletedCallbackTriggered=true
- } catch (e: IOException) {
- completeCallback(e.localizedMessage, false)
- e.printStackTrace()
- }
- }
-
- } catch (e: IOException) {
- completeCallback(e.localizedMessage, false)
- }
- if(!isCompletedCallbackTriggered)
- {
- completeCallback("something went wrong", false)
- }
- }
-
-
-
- }
-}
diff --git a/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioExtractor.kt b/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioExtractor.kt
deleted file mode 100644
index c655182..0000000
--- a/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioExtractor.kt
+++ /dev/null
@@ -1,112 +0,0 @@
-package com.reactnativecompressor.Audio
-
-import android.annotation.SuppressLint
-import android.media.MediaCodec
-import android.media.MediaExtractor
-import android.media.MediaFormat
-import android.media.MediaMetadataRetriever
-import android.media.MediaMuxer
-import android.util.Log
-import java.io.IOException
-import java.nio.ByteBuffer
-
-
-class AudioExtractor {
- /**
- * @param srcPath the path of source video file.
- * @param dstPath the path of destination video file.
- * @param startMs starting time in milliseconds for trimming. Set to
- * negative if starting from beginning.
- * @param endMs end time for trimming in milliseconds. Set to negative if
- * no trimming at the end.
- * @param useAudio true if keep the audio track from the source.
- * @param useVideo true if keep the video track from the source.
- * @throws IOException
- */
- @SuppressLint("NewApi", "WrongConstant")
- @Throws(IOException::class)
- fun genVideoUsingMuxer(srcPath: String?, dstPath: String?, startMs: Int, endMs: Int, useAudio: Boolean, useVideo: Boolean) {
- // Set up MediaExtractor to read from the source.
- val extractor = MediaExtractor()
- extractor.setDataSource(srcPath!!)
- val trackCount = extractor.trackCount
- // Set up MediaMuxer for the destination.
- val muxer: MediaMuxer
- muxer = MediaMuxer(dstPath!!, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4)
- // Set up the tracks and retrieve the max buffer size for selected
- // tracks.
- val indexMap = HashMap<Int, Int>(trackCount)
- var bufferSize = -1
- for (i in 0 until trackCount) {
- val format = extractor.getTrackFormat(i)
- val mime = format.getString(MediaFormat.KEY_MIME)
- var selectCurrentTrack = false
- if (mime!!.startsWith("audio/") && useAudio) {
- selectCurrentTrack = true
- } else if (mime.startsWith("video/") && useVideo) {
- selectCurrentTrack = true
- }
- if (selectCurrentTrack) {
- extractor.selectTrack(i)
- val dstIndex = muxer.addTrack(format)
- indexMap[i] = dstIndex
- if (format.containsKey(MediaFormat.KEY_MAX_INPUT_SIZE)) {
- val newSize = format.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE)
- bufferSize = if (newSize > bufferSize) newSize else bufferSize
- }
- }
- }
- if (bufferSize < 0) {
- bufferSize = DEFAULT_BUFFER_SIZE
- }
- // Set up the orientation and starting time for extractor.
- val retrieverSrc = MediaMetadataRetriever()
- retrieverSrc.setDataSource(srcPath)
- val degreesString = retrieverSrc.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION)
- if (degreesString != null) {
- val degrees = degreesString.toInt()
- if (degrees >= 0) {
- muxer.setOrientationHint(degrees)
- }
- }
- if (startMs > 0) {
- extractor.seekTo((startMs * 1000).toLong(), MediaExtractor.SEEK_TO_CLOSEST_SYNC)
- }
- // Copy the samples from MediaExtractor to MediaMuxer. We will loop
- // for copying each sample and stop when we get to the end of the source
- // file or exceed the end time of the trimming.
- val offset = 0
- var trackIndex = -1
- val dstBuf = ByteBuffer.allocate(bufferSize)
- val bufferInfo = MediaCodec.BufferInfo()
- muxer.start()
- while (true) {
- bufferInfo.offset = offset
- bufferInfo.size = extractor.readSampleData(dstBuf, offset)
- if (bufferInfo.size < 0) {
- Log.d(TAG, "Saw input EOS.")
- bufferInfo.size = 0
- break
- } else {
- bufferInfo.presentationTimeUs = extractor.sampleTime
- if (endMs > 0 && bufferInfo.presentationTimeUs > endMs * 1000) {
- Log.d(TAG, "The current sample is over the trim end time.")
- break
- } else {
- bufferInfo.flags = extractor.sampleFlags
- trackIndex = extractor.sampleTrackIndex
- muxer.writeSampleData(indexMap[trackIndex]!!, dstBuf, bufferInfo)
- extractor.advance()
- }
- }
- }
- muxer.stop()
- muxer.release()
- return
- }
-
- companion object {
- private const val DEFAULT_BUFFER_SIZE = 1 * 1024 * 1024
- private const val TAG = "AudioExtractorDecoder"
- }
-}
diff --git a/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioHelper.kt b/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioHelper.kt
deleted file mode 100644
index 42040b4..0000000
--- a/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioHelper.kt
+++ /dev/null
@@ -1,72 +0,0 @@
-package com.reactnativecompressor.Audio
-
-import android.media.MediaExtractor
-import android.media.MediaFormat
-import com.facebook.react.bridge.ReadableMap
-import com.reactnativecompressor.Utils.Utils
-import java.io.File
-import java.io.IOException
-
-
-class AudioHelper {
-
- var quality: String? = "medium"
- var bitrate: Int = -1
- var samplerate: Int = -1
- var channels: Int = -1
- var progressDivider: Int? = 0
-
- companion object {
- fun fromMap(map: ReadableMap): AudioHelper {
- val options = AudioHelper()
- val iterator = map.keySetIterator()
- while (iterator.hasNextKey()) {
- val key = iterator.nextKey()
- when (key) {
- "quality" -> options.quality = map.getString(key)
- "bitrate" -> {
- val bitrate = map.getInt(key)
- options.bitrate = if (bitrate > 320000 || bitrate < 64000) 64000 else bitrate
- }
- "samplerate" -> options.samplerate = map.getInt(key)
- "channels" -> options.channels = map.getInt(key)
- }
- }
- return options
- }
-
-
- fun getAudioBitrate(path: String): Int {
- val file = File(path)
- val fileSize = file.length() * 8 // size in bits
-
- val mex = MediaExtractor()
- try {
- mex.setDataSource(path)
- } catch (e: IOException) {
- e.printStackTrace()
- }
-
- val mf = mex.getTrackFormat(0)
- val durationUs = mf.getLong(MediaFormat.KEY_DURATION)
- val durationSec = durationUs / 1_000_000.0 // convert duration to seconds
-
- return (fileSize / durationSec).toInt()/1000 // bitrate in bits per second
- }
- fun getDestinationBitrateByQuality(path: String, quality: String): Int {
- val originalBitrate = getAudioBitrate(path)
- var destinationBitrate = originalBitrate
- Utils.addLog("source bitrate: $originalBitrate")
-
- when (quality.lowercase()) {
- "low" -> destinationBitrate = maxOf(64, (originalBitrate * 0.3).toInt())
- "medium" -> destinationBitrate = (originalBitrate * 0.5).toInt()
- "high" -> destinationBitrate = minOf(320, (originalBitrate * 0.7).toInt())
- else -> Utils.addLog("Invalid quality level. Please enter 'low', 'medium', or 'high'.")
- }
-
- return destinationBitrate
- }
-
- }
-}
diff --git a/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioMain.kt b/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioMain.kt
index 446d4fb..f021909 100644
--- a/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioMain.kt
+++ b/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Audio/AudioMain.kt
@@ -11,7 +11,9 @@ class AudioMain(private val reactContext: ReactApplicationContext) {
promise: Promise) {
try {
- AudioCompressor.CompressAudio(fileUrl,optionMap,reactContext,promise)
+ // Skip compression on Android to avoid libandroidlame dependency
+ // Return the original file URL without compression
+ promise.resolve(fileUrl)
} catch (ex: Exception) {
promise.reject(ex)
}
diff --git a/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Utils/Utils.kt b/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Utils/Utils.kt
index c14b727..1198908 100644
--- a/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Utils/Utils.kt
+++ b/node_modules/react-native-compressor/android/src/main/java/com/reactnativecompressor/Utils/Utils.kt
@@ -7,7 +7,6 @@ import android.provider.OpenableColumns
import android.util.Log
import com.facebook.react.bridge.Promise
import com.facebook.react.bridge.ReactApplicationContext
-import com.reactnativecompressor.Audio.AudioCompressor
import com.reactnativecompressor.Video.VideoCompressor.CompressionListener
import com.reactnativecompressor.Video.VideoCompressor.VideoCompressorClass
import java.io.FileNotFoundException
@@ -152,10 +151,6 @@ object Utils {
}
}
- fun addLog(log: String) {
- Log.d(AudioCompressor.TAG, log)
- }
-
val exifAttributes = arrayOf(
"FNumber",
"ApertureValue",
@@ -0,0 +1,59 @@
diff --git a/android/build.gradle b/android/build.gradle
index 5071139f8ee5fbba085d2afe3b2093de8eda915c..84bee34a238c6510169f6b6bdb0fda0594c77136 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -115,7 +115,6 @@ dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4"
implementation 'org.mp4parser:isoparser:1.9.56'
- implementation 'com.github.banketree:AndroidLame-kotlin:v0.0.1'
implementation 'javazoom:jlayer:1.0.1'
}
diff --git a/android/src/main/java/com/reactnativecompressor/Audio/AudioCompressor.kt b/android/src/main/java/com/reactnativecompressor/Audio/AudioCompressor.kt
deleted file mode 100644
index 9292d3ee50776bd9d7760b8dcf6d123d44b4e31b..0000000000000000000000000000000000000000
diff --git a/android/src/main/java/com/reactnativecompressor/Audio/AudioExtractor.kt b/android/src/main/java/com/reactnativecompressor/Audio/AudioExtractor.kt
deleted file mode 100644
index c6551828014437a14dc8f2f19488b647dba1bbe1..0000000000000000000000000000000000000000
diff --git a/android/src/main/java/com/reactnativecompressor/Audio/AudioHelper.kt b/android/src/main/java/com/reactnativecompressor/Audio/AudioHelper.kt
deleted file mode 100644
index 42040b4916573463415ef2f57789b3c4fa25d135..0000000000000000000000000000000000000000
diff --git a/android/src/main/java/com/reactnativecompressor/Audio/AudioMain.kt b/android/src/main/java/com/reactnativecompressor/Audio/AudioMain.kt
index 446d4fb8b69e7cfdb51b29603aa2d52aac1ab8c8..f02190992dac823b6bbf2d77880a25adc48f16c7 100644
--- a/android/src/main/java/com/reactnativecompressor/Audio/AudioMain.kt
+++ b/android/src/main/java/com/reactnativecompressor/Audio/AudioMain.kt
@@ -11,7 +11,9 @@ class AudioMain(private val reactContext: ReactApplicationContext) {
promise: Promise) {
try {
- AudioCompressor.CompressAudio(fileUrl,optionMap,reactContext,promise)
+ // Skip compression on Android to avoid libandroidlame dependency
+ // Return the original file URL without compression
+ promise.resolve(fileUrl)
} catch (ex: Exception) {
promise.reject(ex)
}
diff --git a/android/src/main/java/com/reactnativecompressor/Utils/Utils.kt b/android/src/main/java/com/reactnativecompressor/Utils/Utils.kt
index c14b727e930f4114765bfbe15b742ddcdeaa392f..1198908fcc66eeeea5e537085d7632a0d4b04545 100644
--- a/android/src/main/java/com/reactnativecompressor/Utils/Utils.kt
+++ b/android/src/main/java/com/reactnativecompressor/Utils/Utils.kt
@@ -7,7 +7,6 @@ import android.provider.OpenableColumns
import android.util.Log
import com.facebook.react.bridge.Promise
import com.facebook.react.bridge.ReactApplicationContext
-import com.reactnativecompressor.Audio.AudioCompressor
import com.reactnativecompressor.Video.VideoCompressor.CompressionListener
import com.reactnativecompressor.Video.VideoCompressor.VideoCompressorClass
import java.io.FileNotFoundException
@@ -152,10 +151,6 @@ object Utils {
}
}
- fun addLog(log: String) {
- Log.d(AudioCompressor.TAG, log)
- }
-
val exifAttributes = arrayOf(
"FNumber",
"ApertureValue",
@@ -1,17 +0,0 @@
diff --git a/node_modules/react-native-date-picker/ios/RNDatePicker.h b/node_modules/react-native-date-picker/ios/RNDatePicker.h
index 480746e..470dc3a 100644
--- a/node_modules/react-native-date-picker/ios/RNDatePicker.h
+++ b/node_modules/react-native-date-picker/ios/RNDatePicker.h
@@ -15,6 +15,7 @@ NS_ASSUME_NONNULL_END
#else
#import "DatePicker.h"
#import <UIKit/UIKit.h>
+#include <string>
@interface RNDatePicker : DatePicker
@@ -22,4 +23,3 @@ NS_ASSUME_NONNULL_END
@end
#endif
-
@@ -0,0 +1,17 @@
diff --git a/ios/RNDatePicker.h b/ios/RNDatePicker.h
index 480746eb7acfbe86f67547d9e1de7a5be4d5faf2..13d30cb547195993dfcb4005cc0d248de9ac391a 100644
--- a/ios/RNDatePicker.h
+++ b/ios/RNDatePicker.h
@@ -15,6 +15,7 @@ NS_ASSUME_NONNULL_END
#else
#import "DatePicker.h"
#import <UIKit/UIKit.h>
+#include <string>
@interface RNDatePicker : DatePicker
@@ -22,4 +23,3 @@ NS_ASSUME_NONNULL_END
@end
#endif
-
@@ -1,7 +1,7 @@
diff --git a/node_modules/react-native-drawer-layout/lib/module/views/Drawer.native.js b/node_modules/react-native-drawer-layout/lib/module/views/Drawer.native.js
index 40fdcdb..770fd67 100644
--- a/node_modules/react-native-drawer-layout/lib/module/views/Drawer.native.js
+++ b/node_modules/react-native-drawer-layout/lib/module/views/Drawer.native.js
diff --git a/lib/module/views/Drawer.native.js b/lib/module/views/Drawer.native.js
index 38470a658878a63919186257041098747ec55473..b9d25798c9be229efeb676166f89bfbc72615793 100644
--- a/lib/module/views/Drawer.native.js
+++ b/lib/module/views/Drawer.native.js
@@ -124,15 +124,21 @@ export function Drawer({
}
onTransitionEnd?.(!open);
@@ -1,7 +1,7 @@
diff --git a/node_modules/react-native-keyboard-controller/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts b/node_modules/react-native-keyboard-controller/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts
index 24a25ae..2c5ff6d 100644
--- a/node_modules/react-native-keyboard-controller/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts
+++ b/node_modules/react-native-keyboard-controller/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts
diff --git a/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts b/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts
index 0f6d7c67a307885310ab184fdf9e7a5c7b296825..1e0bdd5b1d3b1eceb47bfb0050da84061fd7f77c 100644
--- a/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts
+++ b/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts
@@ -1,8 +1,6 @@
import { useCallback } from "react";
-import { Platform } from "react-native";
@@ -1,11 +1,11 @@
diff --git a/node_modules/react-native-pager-view/ios/RNCPagerView.m b/node_modules/react-native-pager-view/ios/RNCPagerView.m
index adfc7c6..366df60 100644
--- a/node_modules/react-native-pager-view/ios/RNCPagerView.m
+++ b/node_modules/react-native-pager-view/ios/RNCPagerView.m
diff --git a/ios/RNCPagerView.m b/ios/RNCPagerView.m
index adfc7c6f2224b898a02319d352bb4fe11a18fd7e..939bb801c5b0ca6f93b77cb0507c19d137e08e77 100644
--- a/ios/RNCPagerView.m
+++ b/ios/RNCPagerView.m
@@ -498,6 +498,25 @@ - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecogni
return YES;
}
+ // iOS 26+ full-screen back gesture (interactiveContentPopGestureRecognizer)
+ if (@available(iOS 26, *)) {
+ if (gestureRecognizer == self.panGestureRecognizer &&
@@ -1,7 +1,7 @@
diff --git a/node_modules/react-native-reanimated/lib/module/component/PerformanceMonitor.js b/node_modules/react-native-reanimated/lib/module/component/PerformanceMonitor.js
index 9c98d6c..70ada9f 100644
--- a/node_modules/react-native-reanimated/lib/module/component/PerformanceMonitor.js
+++ b/node_modules/react-native-reanimated/lib/module/component/PerformanceMonitor.js
diff --git a/lib/module/component/PerformanceMonitor.js b/lib/module/component/PerformanceMonitor.js
index 9c98d6cc395419f50969753a4e4c7962b7be588f..3686a97280ac540efa0814ac4dea40358860a76f 100644
--- a/lib/module/component/PerformanceMonitor.js
+++ b/lib/module/component/PerformanceMonitor.js
@@ -1,125 +1,5 @@
'use strict';
@@ -169,10 +169,11 @@ index 9c98d6c..70ada9f 100644
- }
-});
//# sourceMappingURL=PerformanceMonitor.js.map
diff --git a/node_modules/react-native-reanimated/src/component/PerformanceMonitor.tsx b/node_modules/react-native-reanimated/src/component/PerformanceMonitor.tsx
index ff8fc8a..34dde79 100644
--- a/node_modules/react-native-reanimated/src/component/PerformanceMonitor.tsx
+++ b/node_modules/react-native-reanimated/src/component/PerformanceMonitor.tsx
\ No newline at end of file
diff --git a/src/component/PerformanceMonitor.tsx b/src/component/PerformanceMonitor.tsx
index ff8fc8a947a0aeb959e21ec061882c3d190a2ce0..34dde79727765623df80dbcdab5016de6fd5d82c 100644
--- a/src/component/PerformanceMonitor.tsx
+++ b/src/component/PerformanceMonitor.tsx
@@ -1,170 +1,5 @@
'use strict';
@@ -1,7 +1,7 @@
diff --git a/node_modules/react-native-svg/android/src/main/java/com/horcrux/svg/PathView.java b/node_modules/react-native-svg/android/src/main/java/com/horcrux/svg/PathView.java
index 06829bd..1b15818 100644
--- a/node_modules/react-native-svg/android/src/main/java/com/horcrux/svg/PathView.java
+++ b/node_modules/react-native-svg/android/src/main/java/com/horcrux/svg/PathView.java
diff --git a/android/src/main/java/com/horcrux/svg/PathView.java b/android/src/main/java/com/horcrux/svg/PathView.java
index 06829bd00dbded262e1871aaf6db3ae0cfa9d1b1..1b158185a6d7e907aa18ddc806902fcc2bd51027 100644
--- a/android/src/main/java/com/horcrux/svg/PathView.java
+++ b/android/src/main/java/com/horcrux/svg/PathView.java
@@ -14,17 +14,33 @@ import android.graphics.Paint;
import android.graphics.Path;
import com.facebook.react.bridge.ReactContext;
@@ -1,7 +1,7 @@
diff --git a/node_modules/react-native-uitextview/ios/RNUITextViewShadow.swift b/node_modules/react-native-uitextview/ios/RNUITextViewShadow.swift
index c34ba71..3602856 100644
--- a/node_modules/react-native-uitextview/ios/RNUITextViewShadow.swift
+++ b/node_modules/react-native-uitextview/ios/RNUITextViewShadow.swift
diff --git a/ios/RNUITextViewShadow.swift b/ios/RNUITextViewShadow.swift
index c34ba712ca628ed8cf2db0f9fc332810ec86d34d..3602856dc8cd926b5321b4ecb109be9c00a23fe6 100644
--- a/ios/RNUITextViewShadow.swift
+++ b/ios/RNUITextViewShadow.swift
@@ -159,13 +159,25 @@ class RNUITextViewShadow: RCTShadowView {
let maxSize = CGSize(width: CGFloat(maxWidth), height: CGFloat(MAXFLOAT))
let textSize = self.attributedText.boundingRect(with: maxSize, options: .usesLineFragmentOrigin, context: nil)
@@ -1,7 +1,7 @@
diff --git a/node_modules/react-native-view-shot/src/index.js b/node_modules/react-native-view-shot/src/index.js
index fa76d7e..018b686 100644
--- a/node_modules/react-native-view-shot/src/index.js
+++ b/node_modules/react-native-view-shot/src/index.js
diff --git a/src/index.js b/src/index.js
index fa76d7e1272e7fbe4bbd153104db127f1f6eecad..018b6860b7fa02d498d73b5fd06028bae99abedb 100644
--- a/src/index.js
+++ b/src/index.js
@@ -125,13 +125,17 @@ export function captureRef<T: React$ElementType>(
}
}
+168
View File
@@ -0,0 +1,168 @@
diff --git a/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.h b/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.h
index 914a2494a57923fbf185644b7e2bb8aca8848e56..0deac55f22350f5e8377d8963fb1c2434bf6abfd 100644
--- a/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.h
+++ b/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.h
@@ -19,6 +19,8 @@ NS_ASSUME_NONNULL_BEGIN
*/
@interface RCTPullToRefreshViewComponentView : RCTViewComponentView <RCTCustomPullToRefreshViewProtocol>
+- (void)beginRefreshingProgrammatically;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm b/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm
index 1494fd225aff1fa0429e917404d6b4ca5fc961c5..df643f5c844ad2e684de5161528eba17f4a188d0 100644
--- a/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm
+++ b/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm
@@ -1038,6 +1038,11 @@ - (void)_adjustForMaintainVisibleContentPosition
}
}
++ (BOOL)shouldBeRecycled
+{
+ return NO;
+}
+
@end
Class<RCTComponentViewProtocol> RCTScrollViewCls(void)
diff --git a/React/Views/RefreshControl/RCTRefreshControl.h b/React/Views/RefreshControl/RCTRefreshControl.h
index e9b330fa7c29c42653a3b0191d0f8a1b13b2d3de..ec5f58c887bfd949f1279ef1c31352e0b465e9ec 100644
--- a/React/Views/RefreshControl/RCTRefreshControl.h
+++ b/React/Views/RefreshControl/RCTRefreshControl.h
@@ -15,5 +15,8 @@
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) RCTDirectEventBlock onRefresh;
@property (nonatomic, weak) UIScrollView *scrollView;
+@property (nonatomic, copy) UIColor *customTintColor;
+
+- (void)forwarderBeginRefreshing;
@end
diff --git a/React/Views/RefreshControl/RCTRefreshControl.m b/React/Views/RefreshControl/RCTRefreshControl.m
index 53bfd04703502d5b8e932c47a528bb03cd79d330..ff1b1ed5e060bcf0d91528c6d3c2c5c8acf24967 100644
--- a/React/Views/RefreshControl/RCTRefreshControl.m
+++ b/React/Views/RefreshControl/RCTRefreshControl.m
@@ -23,6 +23,7 @@ @implementation RCTRefreshControl {
UIColor *_titleColor;
CGFloat _progressViewOffset;
BOOL _hasMovedToWindow;
+ UIColor *_customTintColor;
}
- (instancetype)init
@@ -58,6 +59,12 @@ - (void)layoutSubviews
_isInitialRender = false;
}
+- (void)didMoveToSuperview
+{
+ [super didMoveToSuperview];
+ [self setTintColor:_customTintColor];
+}
+
- (void)didMoveToWindow
{
[super didMoveToWindow];
@@ -221,4 +228,50 @@ - (void)refreshControlValueChanged
}
}
+// Fix for https://github.com/facebook/react-native/issues/43388
+// A bug in iOS 17.4 causes the haptic to not play when refreshing if the tintColor
+// is set before the refresh control gets added to the scrollview. We'll call this
+// function whenever the superview changes. We'll also call it if the value of customTintColor
+// changes.
+- (void)setTintColor:(UIColor *)tintColor
+{
+ if ([self.superview isKindOfClass:[UIScrollView class]] && self.tintColor != tintColor) {
+ [super setTintColor:tintColor];
+ }
+}
+
+// This method is used by Bluesky's ExpoScrollForwarder. This allows other React Native
+// libraries to perform a refresh of a scrollview and access the refresh control's onRefresh
+// function.
+- (void)forwarderBeginRefreshing
+{
+ _refreshingProgrammatically = NO;
+
+ [self sizeToFit];
+
+ if (!self.scrollView) {
+ return;
+ }
+
+ UIScrollView *scrollView = (UIScrollView *)self.scrollView;
+
+ [UIView animateWithDuration:0.3
+ delay:0
+ options:UIViewAnimationOptionBeginFromCurrentState
+ animations:^(void) {
+ // Whenever we call this method, the scrollview will always be at a position of
+ // -130 or less. Scrolling back to -65 simulates the default behavior of RCTRefreshControl
+ [scrollView setContentOffset:CGPointMake(0, -65)];
+ }
+ completion:^(__unused BOOL finished) {
+ [super beginRefreshing];
+ [self setCurrentRefreshingState:super.refreshing];
+
+ if (self->_onRefresh) {
+ self->_onRefresh(nil);
+ }
+ }
+ ];
+}
+
@end
diff --git a/React/Views/RefreshControl/RCTRefreshControlManager.m b/React/Views/RefreshControl/RCTRefreshControlManager.m
index 40aaf9c51ebda9fedb1d1db2e9aacec84b4c39c8..1c60164b69762997b3369b46609a07768a06bad3 100644
--- a/React/Views/RefreshControl/RCTRefreshControlManager.m
+++ b/React/Views/RefreshControl/RCTRefreshControlManager.m
@@ -22,11 +22,12 @@ - (UIView *)view
RCT_EXPORT_VIEW_PROPERTY(onRefresh, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(refreshing, BOOL)
-RCT_EXPORT_VIEW_PROPERTY(tintColor, UIColor)
RCT_EXPORT_VIEW_PROPERTY(title, NSString)
RCT_EXPORT_VIEW_PROPERTY(titleColor, UIColor)
RCT_EXPORT_VIEW_PROPERTY(progressViewOffset, CGFloat)
+RCT_REMAP_VIEW_PROPERTY(tintColor, customTintColor, UIColor)
+
RCT_EXPORT_METHOD(setNativeRefreshing : (nonnull NSNumber *)viewTag toRefreshing : (BOOL)refreshing)
{
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.kt b/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.kt
index 8b6571698fc5dd091a0d8980a33bb40295faf305..27c97bfeb6f13907c89f1d85f2bb8b8af7bdfb43 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.kt
+++ b/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.kt
@@ -313,8 +313,9 @@ public open class JavaTimerManager(
// We also capture the idleCallbackRunnable to tentatively fix:
// https://github.com/facebook/react-native/issues/44842
currentIdleCallbackRunnable?.cancel()
- currentIdleCallbackRunnable = IdleCallbackRunnable(frameTimeNanos)
- reactApplicationContext.runOnJSQueueThread(currentIdleCallbackRunnable)
+ val idleCallbackRunnable = IdleCallbackRunnable(frameTimeNanos)
+ currentIdleCallbackRunnable = idleCallbackRunnable
+ reactApplicationContext.runOnJSQueueThread(idleCallbackRunnable)
reactChoreographer.postFrameCallback(ReactChoreographer.CallbackType.IDLE_EVENT, this)
}
}
diff --git a/third-party-podspecs/fmt.podspec b/third-party-podspecs/fmt.podspec
index 2f38990e226c13f483aaf1b986302d4094243814..9b02e481e290299be20a6f09c42056ff51695e9b 100644
--- a/third-party-podspecs/fmt.podspec
+++ b/third-party-podspecs/fmt.podspec
@@ -26,4 +26,11 @@ Pod::Spec.new do |spec|
spec.public_header_files = "include/fmt/*.h"
spec.header_mappings_dir = "include"
spec.source_files = ["include/fmt/*.h", "src/format.cc"]
+
+ # TODO: Remove after upgrading React Native past 0.83.x
+ # Fix fmt 11.0.2 consteval build error with Xcode 26.4 (facebook/react-native#55601)
+ # Fixed in RN 0.84+ which bumps fmt to a compatible version.
+ spec.prepare_command = <<~SCRIPT
+ perl -i -pe 's/^# define FMT_USE_CONSTEVAL 1$/# define FMT_USE_CONSTEVAL 0/' include/fmt/base.h
+ SCRIPT
end
@@ -1,7 +1,7 @@
diff --git a/node_modules/sonner-native/lib/commonjs/toast.js b/node_modules/sonner-native/lib/commonjs/toast.js
index 121816a..0c3c7bd 100644
--- a/node_modules/sonner-native/lib/commonjs/toast.js
+++ b/node_modules/sonner-native/lib/commonjs/toast.js
diff --git a/lib/commonjs/toast.js b/lib/commonjs/toast.js
index 121816a452339c1088aeba87928ff63a0bdacca5..47e74bce47323201f0bb4e5ed9dc55b373c07b97 100644
--- a/lib/commonjs/toast.js
+++ b/lib/commonjs/toast.js
@@ -264,7 +264,7 @@ const Toast = exports.Toast = /*#__PURE__*/React.forwardRef(({
...toastSwipeHandlerProps,
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, {