about summary refs log tree commit diff
path: root/src/view/com/lightbox/ImageViewing/index.tsx
diff options
context:
space:
mode:
authordan <dan.abramov@gmail.com>2024-11-08 17:48:01 +0000
committerGitHub <noreply@github.com>2024-11-08 17:48:01 +0000
commitce8d62f8c98182b6498c853c436ae13afa7e21e0 (patch)
tree0e89961d8e19f36079bdb5b3c0c3adcf9746e229 /src/view/com/lightbox/ImageViewing/index.tsx
parent7c45f7dcc7044f46b6d2a3596130db2a108c5e2e (diff)
downloadvoidsky-ce8d62f8c98182b6498c853c436ae13afa7e21e0.tar.zst
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
Diffstat (limited to 'src/view/com/lightbox/ImageViewing/index.tsx')
-rw-r--r--src/view/com/lightbox/ImageViewing/index.tsx44
1 files changed, 28 insertions, 16 deletions
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 {