[APP-1083] bug fix: videos not accurately autoplaying on web (#8692)

* update: auto play video on web with intersection position

* place back the threshold: 0.5

* update: optimize the intersection observer with a throttled scroll listener

---------

Co-authored-by: Anastasiya <anastasiya@Mac.localdomain>
Co-authored-by: Anastasiya <anastasiya@Anastasiyas-MacBook-Pro.local>
This commit is contained in:
Anastasiya Uraleva
2025-08-04 06:17:50 -07:00
committed by GitHub
parent 14e39c4aec
commit 9aa35e9fbb
@@ -138,22 +138,53 @@ function ViewportObserver({
useEffect(() => {
if (!ref.current) return
if (isFullscreen && !isFirefox) return
let scrollTimeout: NodeJS.Timeout | null = null
let lastObserverEntry: IntersectionObserverEntry | null = null
const updatePositionFromEntry = () => {
if (!lastObserverEntry) return
const rect = lastObserverEntry.boundingClientRect
const position = rect.y + rect.height / 2
sendPosition(position)
}
const handleScroll = () => {
if (scrollTimeout) {
clearTimeout(scrollTimeout)
}
scrollTimeout = setTimeout(updatePositionFromEntry, 4) // ~240fps
}
const observer = new IntersectionObserver(
entries => {
const entry = entries[0]
if (!entry) return
const position =
entry.boundingClientRect.y + entry.boundingClientRect.height / 2
sendPosition(position)
lastObserverEntry = entry
setNearScreen(entry.isIntersecting)
const rect = entry.boundingClientRect
const position = rect.y + rect.height / 2
sendPosition(position)
},
{threshold: Array.from({length: 101}, (_, i) => i / 100)},
{threshold: [0, 0.1, 0.25, 0.5, 0.75, 1.0]},
)
observer.observe(ref.current)
return () => observer.disconnect()
}, [sendPosition, isFullscreen])
// In case scrolling hasn't started yet, send up the position
observer.observe(ref.current)
if (nearScreen) {
window.addEventListener('scroll', handleScroll, {passive: true})
}
return () => {
observer.disconnect()
if (scrollTimeout) {
clearTimeout(scrollTimeout)
}
window.removeEventListener('scroll', handleScroll)
}
}, [sendPosition, isFullscreen, nearScreen])
// In case scrolling hasn't started yet, send the original position
useEffect(() => {
if (ref.current && !isAnyViewActive) {
const rect = ref.current.getBoundingClientRect()