diff --git a/package.json b/package.json index 08e3e22bea..86c06d9943 100644 --- a/package.json +++ b/package.json @@ -91,6 +91,7 @@ "@bsky.app/react-native-mmkv": "2.12.5", "@bsky.app/sift": "^0.3.3", "@bsky.app/tapper": "^0.5.1", + "@bsky.app/video": "0.3.4", "@discord/bottom-sheet": "bluesky-social/react-native-bottom-sheet", "@emoji-mart/data": "^1.2.1", "@emoji-mart/react": "^1.1.1", @@ -108,7 +109,6 @@ "@fortawesome/react-native-fontawesome": "^0.3.2", "@growthbook/growthbook": "^1.6.5", "@growthbook/growthbook-react": "^1.6.5", - "@haileyok/bluesky-video": "0.3.2", "@ipld/dag-cbor": "^9.2.0", "@lingui/core": "^5.9.2", "@lingui/react": "^5.9.2", diff --git a/patches/@haileyok+bluesky-video+0.3.2.patch b/patches/@haileyok+bluesky-video+0.3.2.patch deleted file mode 100644 index faaf6c4c53..0000000000 --- a/patches/@haileyok+bluesky-video+0.3.2.patch +++ /dev/null @@ -1,136 +0,0 @@ -diff --git a/node_modules/@haileyok/bluesky-video/android/build.gradle b/node_modules/@haileyok/bluesky-video/android/build.gradle -index b988d3f..7743421 100644 ---- a/node_modules/@haileyok/bluesky-video/android/build.gradle -+++ b/node_modules/@haileyok/bluesky-video/android/build.gradle -@@ -36,6 +36,7 @@ android { - defaultConfig { - versionCode 1 - versionName "0.1.0" -+ consumerProguardFiles 'proguard-rules.pro' - } - lintOptions { - abortOnError false -diff --git a/node_modules/@haileyok/bluesky-video/android/proguard-rules.pro b/node_modules/@haileyok/bluesky-video/android/proguard-rules.pro -new file mode 100644 -index 0000000..3b5b864 ---- /dev/null -+++ b/node_modules/@haileyok/bluesky-video/android/proguard-rules.pro -@@ -0,0 +1,2 @@ -+# Keep FullscreenActivity from being stripped by R8/ProGuard -+-keep class expo.modules.blueskyvideo.FullscreenActivity { *; } -diff --git a/node_modules/@haileyok/bluesky-video/android/src/main/java/expo/modules/blueskyvideo/BlueskyVideoView.kt b/node_modules/@haileyok/bluesky-video/android/src/main/java/expo/modules/blueskyvideo/BlueskyVideoView.kt -index fdabd84..eda8c7c 100644 ---- a/node_modules/@haileyok/bluesky-video/android/src/main/java/expo/modules/blueskyvideo/BlueskyVideoView.kt -+++ b/node_modules/@haileyok/bluesky-video/android/src/main/java/expo/modules/blueskyvideo/BlueskyVideoView.kt -@@ -1,8 +1,11 @@ - package expo.modules.blueskyvideo - -+import android.app.Activity - import android.content.Context - import android.content.Intent - import android.graphics.Color -+import android.os.Build -+import android.util.Log - import android.graphics.Rect - import android.net.Uri - import android.view.ViewGroup -@@ -237,9 +240,44 @@ class BlueskyVideoView( - // Fullscreen handling - - fun enterFullscreen(keepDisplayOn: Boolean) { -- val currentActivity = this.appContext.currentActivity ?: return -+ val tag = "BlueskyVideo" -+ -+ Log.d(tag, "enterFullscreen() called - keepDisplayOn=$keepDisplayOn") -+ Log.d(tag, " isFullscreen=$isFullscreen, isPlaying=$isPlaying, isMuted=$isMuted") -+ Log.d(tag, " player=${player != null}, url=$url") -+ Log.d(tag, " isAttachedToWindow=$isAttachedToWindow, isShown=$isShown") -+ Log.d(tag, " Android SDK: ${Build.VERSION.SDK_INT}, Device: ${Build.MANUFACTURER} ${Build.MODEL}") -+ -+ val currentActivity = this.appContext.currentActivity -+ if (currentActivity == null) { -+ Log.e(tag, "enterFullscreen() FAILED: currentActivity is null") -+ Log.e(tag, " appContext=$appContext") -+ onError(mapOf("error" to "Cannot enter fullscreen: no current activity")) -+ return -+ } -+ -+ Log.d(tag, " currentActivity=$currentActivity") -+ Log.d(tag, " activity.isFinishing=${currentActivity.isFinishing}") -+ Log.d(tag, " activity.isDestroyed=${currentActivity.isDestroyed}") -+ Log.d(tag, " activity.lifecycle=${(currentActivity as? androidx.lifecycle.LifecycleOwner)?.lifecycle?.currentState}") -+ Log.d(tag, " activity.hasWindowFocus=${currentActivity.hasWindowFocus()}") -+ Log.d(tag, " activity.window.isActive=${currentActivity.window?.isActive}") -+ -+ // Check if activity is in a valid state to start another activity -+ if (currentActivity.isFinishing) { -+ Log.e(tag, "enterFullscreen() FAILED: currentActivity is finishing") -+ onError(mapOf("error" to "Cannot enter fullscreen: activity is finishing")) -+ return -+ } -+ -+ if (currentActivity.isDestroyed) { -+ Log.e(tag, "enterFullscreen() FAILED: currentActivity is destroyed") -+ onError(mapOf("error" to "Cannot enter fullscreen: activity is destroyed")) -+ return -+ } - - this.enteredFullscreenMuteState = this.isMuted -+ Log.d(tag, " saved enteredFullscreenMuteState=$enteredFullscreenMuteState") - - // We always want to start with unmuted state and playing. Fire those from here so the - // event dispatcher gets called -@@ -247,18 +285,51 @@ class BlueskyVideoView( - if (!this.isPlaying) { - this.play() - } -+ Log.d(tag, " after unmute/play: isPlaying=$isPlaying, isMuted=$isMuted") - - // Remove the player from this view, but don't null the player! - this.playerView.player = null -+ Log.d(tag, " detached player from playerView") - - // create the intent and give it a view - val intent = Intent(context, FullscreenActivity::class.java) - intent.putExtra("keepDisplayOn", keepDisplayOn) - FullscreenActivity.asscVideoView = WeakReference(this) - -+ Log.d(tag, " intent created: $intent") -+ Log.d(tag, " intent.component=${intent.component}") -+ Log.d(tag, " intent.flags=${intent.flags} (0x${Integer.toHexString(intent.flags)})") -+ Log.d(tag, " context for intent=$context") -+ Log.d(tag, " FullscreenActivity.asscVideoView set to WeakReference(this)") -+ - // fire the fullscreen event and launch the intent -- this.isFullscreen = true -- currentActivity.startActivity(intent) -+ try { -+ Log.d(tag, " calling startActivity()...") -+ currentActivity.startActivity(intent) -+ this.isFullscreen = true -+ Log.d(tag, " startActivity() SUCCESS - isFullscreen set to true") -+ } catch (e: Exception) { -+ Log.e(tag, "enterFullscreen() FAILED: startActivity() threw exception", e) -+ Log.e(tag, " exception class: ${e.javaClass.name}") -+ Log.e(tag, " exception message: ${e.message}") -+ Log.e(tag, " exception cause: ${e.cause}") -+ e.printStackTrace() -+ -+ // Restore state since fullscreen failed -+ this.playerView.player = this.player -+ Log.d(tag, " restored player to playerView after failure") -+ -+ if (this.enteredFullscreenMuteState) { -+ this.mute() -+ Log.d(tag, " restored mute state after failure") -+ } -+ -+ onError(mapOf( -+ "error" to "Failed to enter fullscreen: ${e.message}", -+ "exceptionClass" to e.javaClass.name, -+ "exceptionMessage" to (e.message ?: "unknown") -+ )) -+ } - } - - fun onExitFullscreen() { diff --git a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerNative.tsx b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerNative.tsx index 946df787e7..05e8b84581 100644 --- a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerNative.tsx +++ b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerNative.tsx @@ -1,7 +1,7 @@ import {useImperativeHandle, useRef, useState} from 'react' import {Pressable, type StyleProp, View, type ViewStyle} from 'react-native' import {type AppBskyEmbedVideo} from '@atproto/api' -import {BlueskyVideoView} from '@haileyok/bluesky-video' +import {BlueskyVideoView} from '@bsky.app/video' import {msg} from '@lingui/core/macro' import {useLingui} from '@lingui/react' diff --git a/src/view/com/composer/videos/VideoPreview.tsx b/src/view/com/composer/videos/VideoPreview.tsx index 9736bd5844..f668c4f209 100644 --- a/src/view/com/composer/videos/VideoPreview.tsx +++ b/src/view/com/composer/videos/VideoPreview.tsx @@ -2,7 +2,7 @@ import {useRef} from 'react' import {View} from 'react-native' import {Image} from 'expo-image' import {type ImagePickerAsset} from 'expo-image-picker' -import {BlueskyVideoView} from '@haileyok/bluesky-video' +import {BlueskyVideoView} from '@bsky.app/video' import {type CompressedVideo} from '#/lib/media/video/types' import {clamp} from '#/lib/numbers' diff --git a/src/view/com/util/List.tsx b/src/view/com/util/List.tsx index c8c4007f02..d9a7f06af6 100644 --- a/src/view/com/util/List.tsx +++ b/src/view/com/util/List.tsx @@ -6,7 +6,7 @@ import { useAnimatedScrollHandler, useSharedValue, } from 'react-native-reanimated' -import {updateActiveVideoViewAsync} from '@haileyok/bluesky-video' +import {updateActiveVideoViewAsync} from '@bsky.app/video' import {useDedupe} from '#/lib/hooks/useDedupe' import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' diff --git a/yarn.lock b/yarn.lock index ff02962745..a786aa1eee 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2454,6 +2454,11 @@ resolved "https://registry.yarnpkg.com/@bsky.app/tapper/-/tapper-0.5.1.tgz#7c72e1903435290a29be9f33fe0fcba95bbfa554" integrity sha512-roGmW6Fk9qE8N0u9d74XzX9+MUIr04PElOhfIg0pXtZ1buaORpasLBBC+i6WytxDP2p29CuFdzBXDaBhmcI/ow== +"@bsky.app/video@0.3.4": + version "0.3.4" + resolved "https://registry.yarnpkg.com/@bsky.app/video/-/video-0.3.4.tgz#68c626d025f0005313a8320120540f51bed58da7" + integrity sha512-BTHfdS5hWlpBvMSNhYhsAoBnWtu4BCXYyK/DZ1wA/akXquJP3SuzEGL6B2V0Xdtg2E0rhjJD2njlTj69E64reg== + "@crowdin/cli@^4.14.1": version "4.14.1" resolved "https://registry.yarnpkg.com/@crowdin/cli/-/cli-4.14.1.tgz#1239922681235b6b14bcacd4fd622bc2217dd6c5" @@ -3372,11 +3377,6 @@ dependencies: dom-mutator "^0.6.0" -"@haileyok/bluesky-video@0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@haileyok/bluesky-video/-/bluesky-video-0.3.2.tgz#44dc3974750a9619a4d72e97a0f1678f335028cd" - integrity sha512-CJIS/4HW+x6xqONDZaUljQgMqaaZQnlFjt0afdCSO6VtFk5Fd/ocW+Tc4UulQ6zcCNiL6Y8HJR8sl/EIWHgPDw== - "@humanfs/core@^0.19.1": version "0.19.1" resolved "https://registry.yarnpkg.com/@humanfs/core/-/core-0.19.1.tgz#17c55ca7d426733fe3c561906b8173c336b40a77"