diff options
author | Anastasiya Uraleva <anastasiyauraleva@gmail.com> | 2025-08-04 06:17:50 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-08-04 06:17:50 -0700 |
commit | 9aa35e9fbb6136a88a66388ff5e4644ad25c9e4b (patch) | |
tree | bc528b6390b182fe516a0a9b678c5862492ad092 /src/components/Post | |
parent | 14e39c4aecb8373b692c706bf27e49b0b72918b2 (diff) | |
download | voidsky-9aa35e9fbb6136a88a66388ff5e4644ad25c9e4b.tar.zst |
[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>
Diffstat (limited to 'src/components/Post')
-rw-r--r-- | src/components/Post/Embed/VideoEmbed/index.web.tsx | 45 |
1 files changed, 38 insertions, 7 deletions
diff --git a/src/components/Post/Embed/VideoEmbed/index.web.tsx b/src/components/Post/Embed/VideoEmbed/index.web.tsx index 7f601af47..900bc2188 100644 --- a/src/components/Post/Embed/VideoEmbed/index.web.tsx +++ b/src/components/Post/Embed/VideoEmbed/index.web.tsx @@ -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 + 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() |