about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorSamuel Newman <mozzius@protonmail.com>2025-08-04 18:42:55 +0300
committerGitHub <noreply@github.com>2025-08-04 18:42:55 +0300
commit7b5d11eb80f247173a11c37a6f1bb08824912a54 (patch)
treea2bdddbca7f30d335399d8c70d89a30120671932 /src
parentb32568260f98ea879468fd1bdedacf85d1e6ae8c (diff)
downloadvoidsky-7b5d11eb80f247173a11c37a6f1bb08824912a54.tar.zst
Fix video thumbnails on native (#8774)
Diffstat (limited to 'src')
-rw-r--r--src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerNative.tsx161
-rw-r--r--src/components/Post/Embed/VideoEmbed/index.tsx21
2 files changed, 88 insertions, 94 deletions
diff --git a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerNative.tsx b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerNative.tsx
index 351e9f305..ecc36dc33 100644
--- a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerNative.tsx
+++ b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerNative.tsx
@@ -1,4 +1,4 @@
-import React, {useRef} from 'react'
+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'
@@ -17,91 +17,88 @@ import {MediaInsetBorder} from '#/components/MediaInsetBorder'
 import {useVideoMuteState} from '#/components/Post/Embed/VideoEmbed/VideoVolumeContext'
 import {TimeIndicator} from './TimeIndicator'
 
-export const VideoEmbedInnerNative = React.forwardRef(
-  function VideoEmbedInnerNative(
-    {
-      embed,
-      setStatus,
-      setIsLoading,
-      setIsActive,
-    }: {
-      embed: AppBskyEmbedVideo.View
-      setStatus: (status: 'playing' | 'paused') => void
-      setIsLoading: (isLoading: boolean) => void
-      setIsActive: (isActive: boolean) => void
-    },
-    ref: React.Ref<{togglePlayback: () => void}>,
-  ) {
-    const {_} = useLingui()
-    const videoRef = useRef<BlueskyVideoView>(null)
-    const autoplayDisabled = useAutoplayDisabled()
-    const isWithinMessage = useIsWithinMessage()
-    const [muted, setMuted] = useVideoMuteState()
+export function VideoEmbedInnerNative({
+  ref,
+  embed,
+  setStatus,
+  setIsLoading,
+  setIsActive,
+}: {
+  ref: React.Ref<{togglePlayback: () => void}>
+  embed: AppBskyEmbedVideo.View
+  setStatus: (status: 'playing' | 'paused') => void
+  setIsLoading: (isLoading: boolean) => void
+  setIsActive: (isActive: boolean) => void
+}) {
+  const {_} = useLingui()
+  const videoRef = useRef<BlueskyVideoView>(null)
+  const autoplayDisabled = useAutoplayDisabled()
+  const isWithinMessage = useIsWithinMessage()
+  const [muted, setMuted] = useVideoMuteState()
 
-    const [isPlaying, setIsPlaying] = React.useState(false)
-    const [timeRemaining, setTimeRemaining] = React.useState(0)
-    const [error, setError] = React.useState<string>()
+  const [isPlaying, setIsPlaying] = useState(false)
+  const [timeRemaining, setTimeRemaining] = useState(0)
+  const [error, setError] = useState<string>()
 
-    React.useImperativeHandle(ref, () => ({
-      togglePlayback: () => {
-        videoRef.current?.togglePlayback()
-      },
-    }))
+  useImperativeHandle(ref, () => ({
+    togglePlayback: () => {
+      videoRef.current?.togglePlayback()
+    },
+  }))
 
-    if (error) {
-      throw new Error(error)
-    }
+  if (error) {
+    throw new Error(error)
+  }
 
-    return (
-      <View style={[a.flex_1, a.relative]}>
-        <BlueskyVideoView
-          url={embed.playlist}
-          autoplay={!autoplayDisabled && !isWithinMessage}
-          beginMuted={autoplayDisabled ? false : muted}
-          style={[a.rounded_sm]}
-          onActiveChange={e => {
-            setIsActive(e.nativeEvent.isActive)
-          }}
-          onLoadingChange={e => {
-            setIsLoading(e.nativeEvent.isLoading)
-          }}
-          onMutedChange={e => {
-            setMuted(e.nativeEvent.isMuted)
-          }}
-          onStatusChange={e => {
-            setStatus(e.nativeEvent.status)
-            setIsPlaying(e.nativeEvent.status === 'playing')
-          }}
-          onTimeRemainingChange={e => {
-            setTimeRemaining(e.nativeEvent.timeRemaining)
-          }}
-          onError={e => {
-            setError(e.nativeEvent.error)
-          }}
-          ref={videoRef}
-          accessibilityLabel={
-            embed.alt ? _(msg`Video: ${embed.alt}`) : _(msg`Video`)
-          }
-          accessibilityHint=""
-        />
-        <VideoControls
-          enterFullscreen={() => {
-            videoRef.current?.enterFullscreen(true)
-          }}
-          toggleMuted={() => {
-            videoRef.current?.toggleMuted()
-          }}
-          togglePlayback={() => {
-            videoRef.current?.togglePlayback()
-          }}
-          isPlaying={isPlaying}
-          timeRemaining={timeRemaining}
-        />
-        <MediaInsetBorder />
-      </View>
-    )
-  },
-)
+  return (
+    <View style={[a.flex_1, a.relative]}>
+      <BlueskyVideoView
+        url={embed.playlist}
+        autoplay={!autoplayDisabled && !isWithinMessage}
+        beginMuted={autoplayDisabled ? false : muted}
+        style={[a.rounded_sm]}
+        onActiveChange={e => {
+          setIsActive(e.nativeEvent.isActive)
+        }}
+        onLoadingChange={e => {
+          setIsLoading(e.nativeEvent.isLoading)
+        }}
+        onMutedChange={e => {
+          setMuted(e.nativeEvent.isMuted)
+        }}
+        onStatusChange={e => {
+          setStatus(e.nativeEvent.status)
+          setIsPlaying(e.nativeEvent.status === 'playing')
+        }}
+        onTimeRemainingChange={e => {
+          setTimeRemaining(e.nativeEvent.timeRemaining)
+        }}
+        onError={e => {
+          setError(e.nativeEvent.error)
+        }}
+        ref={videoRef}
+        accessibilityLabel={
+          embed.alt ? _(msg`Video: ${embed.alt}`) : _(msg`Video`)
+        }
+        accessibilityHint=""
+      />
+      <VideoControls
+        enterFullscreen={() => {
+          videoRef.current?.enterFullscreen(true)
+        }}
+        toggleMuted={() => {
+          videoRef.current?.toggleMuted()
+        }}
+        togglePlayback={() => {
+          videoRef.current?.togglePlayback()
+        }}
+        isPlaying={isPlaying}
+        timeRemaining={timeRemaining}
+      />
+      <MediaInsetBorder />
+    </View>
+  )
+}
 
 function VideoControls({
   enterFullscreen,
diff --git a/src/components/Post/Embed/VideoEmbed/index.tsx b/src/components/Post/Embed/VideoEmbed/index.tsx
index 8cb78ff70..c66d1a218 100644
--- a/src/components/Post/Embed/VideoEmbed/index.tsx
+++ b/src/components/Post/Embed/VideoEmbed/index.tsx
@@ -1,4 +1,4 @@
-import React, {useCallback, useState} from 'react'
+import {useCallback, useRef, useState} from 'react'
 import {ActivityIndicator, View} from 'react-native'
 import {ImageBackground} from 'expo-image'
 import {type AppBskyEmbedVideo} from '@atproto/api'
@@ -81,13 +81,13 @@ export function VideoEmbed({embed, crop}: Props) {
 
 function InnerWrapper({embed}: Props) {
   const {_} = useLingui()
-  const ref = React.useRef<{togglePlayback: () => void}>(null)
+  const ref = useRef<{togglePlayback: () => void}>(null)
 
-  const [status, setStatus] = React.useState<'playing' | 'paused' | 'pending'>(
+  const [status, setStatus] = useState<'playing' | 'paused' | 'pending'>(
     'pending',
   )
-  const [isLoading, setIsLoading] = React.useState(false)
-  const [isActive, setIsActive] = React.useState(false)
+  const [isLoading, setIsLoading] = useState(false)
+  const [isActive, setIsActive] = useState(false)
   const showSpinner = useThrottledValue(isActive && isLoading, 100)
 
   const showOverlay =
@@ -96,11 +96,9 @@ function InnerWrapper({embed}: Props) {
     (status === 'paused' && !isActive) ||
     status === 'pending'
 
-  React.useEffect(() => {
-    if (!isActive && status !== 'pending') {
-      setStatus('pending')
-    }
-  }, [isActive, status])
+  if (!isActive && status !== 'pending') {
+    setStatus('pending')
+  }
 
   return (
     <>
@@ -131,8 +129,7 @@ function InnerWrapper({embed}: Props) {
             onPress={() => {
               ref.current?.togglePlayback()
             }}
-            label={_(msg`Play video`)}
-            color="secondary">
+            label={_(msg`Play video`)}>
             {showSpinner ? (
               <View
                 style={[