diff --git a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/VideoControls.tsx b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/VideoControls.tsx index 5a23e595a9..0f5f7fdc78 100644 --- a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/VideoControls.tsx +++ b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/VideoControls.tsx @@ -130,13 +130,14 @@ export function Controls({ const autoplayDisabled = useAutoplayDisabled() || isWithinMessage useEffect(() => { if (active) { - if (onScreen) { + // GIFs play immediately, videos wait until onScreen + if (onScreen || isGif) { if (!autoplayDisabled) play() } else { pause() } } - }, [onScreen, pause, active, play, autoplayDisabled]) + }, [onScreen, pause, active, play, autoplayDisabled, isGif]) // use minimal quality when not focused useEffect(() => { diff --git a/src/components/Post/Embed/VideoEmbed/index.web.tsx b/src/components/Post/Embed/VideoEmbed/index.web.tsx index 19c6c83b2c..aea5b5d413 100644 --- a/src/components/Post/Embed/VideoEmbed/index.web.tsx +++ b/src/components/Post/Embed/VideoEmbed/index.web.tsx @@ -26,15 +26,25 @@ import {IS_WEB_FIREFOX} from '#/env' import {useActiveVideoWeb} from './ActiveVideoWebContext' import * as VideoFallback from './VideoEmbedInner/VideoFallback' +const noop = () => {} + export function VideoEmbed({embed}: {embed: AppBskyEmbedVideo.View}) { const t = useTheme() const ref = useRef(null) - const {active, setActive, sendPosition, currentActiveView} = - useActiveVideoWeb() + const { + active: activeFromContext, + setActive, + sendPosition, + currentActiveView, + } = useActiveVideoWeb() const [onScreen, setOnScreen] = useState(false) const [isFullscreen] = useFullscreen() const lastKnownTime = useRef(undefined) + const isGif = embed.presentation === 'gif' + // GIFs don't participate in the "one video at a time" system + const active = isGif || activeFromContext + useEffect(() => { if (!ref.current) return if (isFullscreen && !IS_WEB_FIREFOX) return @@ -43,15 +53,18 @@ export function VideoEmbed({embed}: {embed: AppBskyEmbedVideo.View}) { const entry = entries[0] if (!entry) return setOnScreen(entry.isIntersecting) - sendPosition( - entry.boundingClientRect.y + entry.boundingClientRect.height / 2, - ) + // GIFs don't send position - they don't compete to be the active video + if (!isGif) { + sendPosition( + entry.boundingClientRect.y + entry.boundingClientRect.height / 2, + ) + } }, {threshold: 0.5}, ) observer.observe(ref.current) return () => observer.disconnect() - }, [sendPosition, isFullscreen]) + }, [sendPosition, isFullscreen, isGif]) const [key, setKey] = useState(0) const renderError = useCallback( @@ -107,7 +120,7 @@ export function VideoEmbed({embed}: {embed: AppBskyEmbedVideo.View}) { return (