From ce8d62f8c98182b6498c853c436ae13afa7e21e0 Mon Sep 17 00:00:00 2001
From: dan <dan.abramov@gmail.com>
Date: Fri, 8 Nov 2024 17:48:01 +0000
Subject: Fix stuck lightbox (#6166)

* Add early exit guards once the gesture is over

* Work around the Reanimated bug

* Move derived reaction upwards to avoid duplicating it
---
 src/view/com/lightbox/ImageViewing/index.tsx | 44 ++++++++++++++++++----------
 1 file changed, 28 insertions(+), 16 deletions(-)

(limited to 'src/view/com/lightbox/ImageViewing/index.tsx')

diff --git a/src/view/com/lightbox/ImageViewing/index.tsx b/src/view/com/lightbox/ImageViewing/index.tsx
index 7a3a50691..0a01c7fb3 100644
--- a/src/view/com/lightbox/ImageViewing/index.tsx
+++ b/src/view/com/lightbox/ImageViewing/index.tsx
@@ -160,6 +160,23 @@ function ImageView({
     }
   }, [])
 
+  useAnimatedReaction(
+    () => {
+      const screenSize = measure(safeAreaRef)
+      return (
+        !screenSize ||
+        Math.abs(dismissSwipeTranslateY.value) > screenSize.height
+      )
+    },
+    (isOut, wasOut) => {
+      if (isOut && !wasOut) {
+        // Stop the animation from blocking the screen forever.
+        cancelAnimation(dismissSwipeTranslateY)
+        runOnJS(onRequestClose)()
+      }
+    },
+  )
+
   return (
     <Animated.View style={[styles.container, containerStyle]}>
       <Animated.View
@@ -256,12 +273,23 @@ function LightboxImage({
     .maxPointers(1)
     .onUpdate(e => {
       'worklet'
+      if (isFlyingAway.value) {
+        return
+      }
       dismissSwipeTranslateY.value = e.translationY
     })
     .onEnd(e => {
       'worklet'
+      if (isFlyingAway.value) {
+        return
+      }
       if (Math.abs(e.velocityY) > 1000) {
         isFlyingAway.value = true
+        if (dismissSwipeTranslateY.value === 0) {
+          // HACK: If the initial value is 0, withDecay() animation doesn't start.
+          // This is a bug in Reanimated, but for now we'll work around it like this.
+          dismissSwipeTranslateY.value = 1
+        }
         dismissSwipeTranslateY.value = withDecay({
           velocity: e.velocityY,
           velocityFactor: Math.max(3000 / Math.abs(e.velocityY), 1), // Speed up if it's too slow.
@@ -274,22 +302,6 @@ function LightboxImage({
         })
       }
     })
-  useAnimatedReaction(
-    () => {
-      const screenSize = measure(safeAreaRef)
-      return (
-        !screenSize ||
-        Math.abs(dismissSwipeTranslateY.value) > screenSize.height
-      )
-    },
-    (isOut, wasOut) => {
-      if (isOut && !wasOut) {
-        // Stop the animation from blocking the screen forever.
-        cancelAnimation(dismissSwipeTranslateY)
-        runOnJS(onRequestClose)()
-      }
-    },
-  )
 
   const imageStyle = useAnimatedStyle(() => {
     return {
-- 
cgit 1.4.1

