From 84f4afd3d75eb50e96e4cee758f41b186f8a510d Mon Sep 17 00:00:00 2001
From: dan <dan.abramov@gmail.com>
Date: Tue, 3 Dec 2024 01:35:36 +0000
Subject: Fix scroll gesture alignment (#6898)

---
 src/view/com/util/MainScrollProvider.tsx | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

(limited to 'src/view/com/util/MainScrollProvider.tsx')

diff --git a/src/view/com/util/MainScrollProvider.tsx b/src/view/com/util/MainScrollProvider.tsx
index 42b2e12df..c1293a83c 100644
--- a/src/view/com/util/MainScrollProvider.tsx
+++ b/src/view/com/util/MainScrollProvider.tsx
@@ -60,15 +60,16 @@ export function MainScrollProvider({children}: {children: React.ReactNode}) {
   const snapToClosestState = useCallback(
     (e: NativeScrollEvent) => {
       'worklet'
+      const offsetY = Math.max(0, e.contentOffset.y)
       if (isNative) {
         const startDragOffsetValue = startDragOffset.get()
         if (startDragOffsetValue === null) {
           return
         }
-        const didScrollDown = e.contentOffset.y > startDragOffsetValue
+        const didScrollDown = offsetY > startDragOffsetValue
         startDragOffset.set(null)
         startMode.set(null)
-        if (e.contentOffset.y < headerHeight.get()) {
+        if (offsetY < headerHeight.get()) {
           // If we're close to the top, show the shell.
           setMode(false)
         } else if (didScrollDown) {
@@ -86,8 +87,9 @@ export function MainScrollProvider({children}: {children: React.ReactNode}) {
   const onBeginDrag = useCallback(
     (e: NativeScrollEvent) => {
       'worklet'
+      const offsetY = Math.max(0, e.contentOffset.y)
       if (isNative) {
-        startDragOffset.set(e.contentOffset.y)
+        startDragOffset.set(offsetY)
         startMode.set(headerMode.get())
       }
     },
@@ -121,14 +123,12 @@ export function MainScrollProvider({children}: {children: React.ReactNode}) {
   const onScroll = useCallback(
     (e: NativeScrollEvent) => {
       'worklet'
+      const offsetY = Math.max(0, e.contentOffset.y)
       if (isNative) {
         const startDragOffsetValue = startDragOffset.get()
         const startModeValue = startMode.get()
         if (startDragOffsetValue === null || startModeValue === null) {
-          if (
-            headerMode.get() !== 0 &&
-            e.contentOffset.y < headerHeight.get()
-          ) {
+          if (headerMode.get() !== 0 && offsetY < headerHeight.get()) {
             // If we're close enough to the top, always show the shell.
             // Even if we're not dragging.
             setMode(false)
@@ -138,7 +138,7 @@ export function MainScrollProvider({children}: {children: React.ReactNode}) {
 
         // The "mode" value is always between 0 and 1.
         // Figure out how much to move it based on the current dragged distance.
-        const dy = e.contentOffset.y - startDragOffsetValue
+        const dy = offsetY - startDragOffsetValue
         const dProgress = interpolate(
           dy,
           [-headerHeight.get(), headerHeight.get()],
@@ -157,10 +157,10 @@ export function MainScrollProvider({children}: {children: React.ReactNode}) {
         }
         // On the web, we don't try to follow the drag because we don't know when it ends.
         // Instead, show/hide immediately based on whether we're scrolling up or down.
-        const dy = e.contentOffset.y - (startDragOffset.get() ?? 0)
-        startDragOffset.set(e.contentOffset.y)
+        const dy = offsetY - (startDragOffset.get() ?? 0)
+        startDragOffset.set(offsetY)
 
-        if (dy < 0 || e.contentOffset.y < WEB_HIDE_SHELL_THRESHOLD) {
+        if (dy < 0 || offsetY < WEB_HIDE_SHELL_THRESHOLD) {
           setMode(false)
         } else if (dy > 0) {
           setMode(true)
-- 
cgit 1.4.1

