From 9aa35e9fbb6136a88a66388ff5e4644ad25c9e4b Mon Sep 17 00:00:00 2001
From: Anastasiya Uraleva <anastasiyauraleva@gmail.com>
Date: Mon, 4 Aug 2025 06:17:50 -0700
Subject: [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>
---
 src/components/Post/Embed/VideoEmbed/index.web.tsx | 45 ++++++++++++++++++----
 1 file changed, 38 insertions(+), 7 deletions(-)

(limited to 'src/components/Post/Embed/VideoEmbed/index.web.tsx')

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()
-- 
cgit 1.4.1

