Exempt gifs from active video system (#9824)

This commit is contained in:
Samuel Newman
2026-02-04 22:37:09 +02:00
committed by GitHub
parent e6c4a539ca
commit 3abc361800
2 changed files with 23 additions and 9 deletions
@@ -130,13 +130,14 @@ export function Controls({
const autoplayDisabled = useAutoplayDisabled() || isWithinMessage const autoplayDisabled = useAutoplayDisabled() || isWithinMessage
useEffect(() => { useEffect(() => {
if (active) { if (active) {
if (onScreen) { // GIFs play immediately, videos wait until onScreen
if (onScreen || isGif) {
if (!autoplayDisabled) play() if (!autoplayDisabled) play()
} else { } else {
pause() pause()
} }
} }
}, [onScreen, pause, active, play, autoplayDisabled]) }, [onScreen, pause, active, play, autoplayDisabled, isGif])
// use minimal quality when not focused // use minimal quality when not focused
useEffect(() => { useEffect(() => {
@@ -26,15 +26,25 @@ import {IS_WEB_FIREFOX} from '#/env'
import {useActiveVideoWeb} from './ActiveVideoWebContext' import {useActiveVideoWeb} from './ActiveVideoWebContext'
import * as VideoFallback from './VideoEmbedInner/VideoFallback' import * as VideoFallback from './VideoEmbedInner/VideoFallback'
const noop = () => {}
export function VideoEmbed({embed}: {embed: AppBskyEmbedVideo.View}) { export function VideoEmbed({embed}: {embed: AppBskyEmbedVideo.View}) {
const t = useTheme() const t = useTheme()
const ref = useRef<HTMLDivElement>(null) const ref = useRef<HTMLDivElement>(null)
const {active, setActive, sendPosition, currentActiveView} = const {
useActiveVideoWeb() active: activeFromContext,
setActive,
sendPosition,
currentActiveView,
} = useActiveVideoWeb()
const [onScreen, setOnScreen] = useState(false) const [onScreen, setOnScreen] = useState(false)
const [isFullscreen] = useFullscreen() const [isFullscreen] = useFullscreen()
const lastKnownTime = useRef<number | undefined>(undefined) const lastKnownTime = useRef<number | undefined>(undefined)
const isGif = embed.presentation === 'gif'
// GIFs don't participate in the "one video at a time" system
const active = isGif || activeFromContext
useEffect(() => { useEffect(() => {
if (!ref.current) return if (!ref.current) return
if (isFullscreen && !IS_WEB_FIREFOX) return if (isFullscreen && !IS_WEB_FIREFOX) return
@@ -43,15 +53,18 @@ export function VideoEmbed({embed}: {embed: AppBskyEmbedVideo.View}) {
const entry = entries[0] const entry = entries[0]
if (!entry) return if (!entry) return
setOnScreen(entry.isIntersecting) setOnScreen(entry.isIntersecting)
sendPosition( // GIFs don't send position - they don't compete to be the active video
entry.boundingClientRect.y + entry.boundingClientRect.height / 2, if (!isGif) {
) sendPosition(
entry.boundingClientRect.y + entry.boundingClientRect.height / 2,
)
}
}, },
{threshold: 0.5}, {threshold: 0.5},
) )
observer.observe(ref.current) observer.observe(ref.current)
return () => observer.disconnect() return () => observer.disconnect()
}, [sendPosition, isFullscreen]) }, [sendPosition, isFullscreen, isGif])
const [key, setKey] = useState(0) const [key, setKey] = useState(0)
const renderError = useCallback( const renderError = useCallback(
@@ -107,7 +120,7 @@ export function VideoEmbed({embed}: {embed: AppBskyEmbedVideo.View}) {
return ( return (
<View style={[a.pt_xs]}> <View style={[a.pt_xs]}>
<ViewportObserver <ViewportObserver
sendPosition={sendPosition} sendPosition={isGif ? noop : sendPosition}
isAnyViewActive={currentActiveView !== null}> isAnyViewActive={currentActiveView !== null}>
<ConstrainedImage <ConstrainedImage
fullBleed fullBleed