about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/state/lightbox.tsx10
-rw-r--r--src/view/com/lightbox/ImageViewing/index.tsx33
2 files changed, 40 insertions, 3 deletions
diff --git a/src/state/lightbox.tsx b/src/state/lightbox.tsx
index 67a450991..3e01d7ef7 100644
--- a/src/state/lightbox.tsx
+++ b/src/state/lightbox.tsx
@@ -31,7 +31,15 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
 
   const openLightbox = useNonReactiveCallback(
     (lightbox: Omit<Lightbox, 'id'>) => {
-      setActiveLightbox({...lightbox, id: nanoid()})
+      setActiveLightbox(prevLightbox => {
+        if (prevLightbox) {
+          // Ignore duplicate open requests. If it's already open,
+          // the user has to explicitly close the previous one first.
+          return prevLightbox
+        } else {
+          return {...lightbox, id: nanoid()}
+        }
+      })
     },
   )
 
diff --git a/src/view/com/lightbox/ImageViewing/index.tsx b/src/view/com/lightbox/ImageViewing/index.tsx
index e7d158d03..ce59b4b9d 100644
--- a/src/view/com/lightbox/ImageViewing/index.tsx
+++ b/src/view/com/lightbox/ImageViewing/index.tsx
@@ -111,14 +111,14 @@ export default function ImageViewRoot({
       )
 
     // https://github.com/software-mansion/react-native-reanimated/issues/6677
-    requestAnimationFrame(() => {
+    rAF_FIXED(() => {
       openProgress.set(() =>
         canAnimate ? withClampedSpring(1, SLOW_SPRING) : 1,
       )
     })
     return () => {
       // https://github.com/software-mansion/react-native-reanimated/issues/6677
-      requestAnimationFrame(() => {
+      rAF_FIXED(() => {
         openProgress.set(() =>
           canAnimate ? withClampedSpring(0, SLOW_SPRING) : 0,
         )
@@ -752,3 +752,32 @@ function withClampedSpring(value: any, config: WithSpringConfig) {
   'worklet'
   return withSpring(value, {...config, overshootClamping: true})
 }
+
+// We have to do this because we can't trust RN's rAF to fire in order.
+// https://github.com/facebook/react-native/issues/48005
+let isFrameScheduled = false
+let pendingFrameCallbacks: Array<() => void> = []
+function rAF_FIXED(callback: () => void) {
+  pendingFrameCallbacks.push(callback)
+  if (!isFrameScheduled) {
+    isFrameScheduled = true
+    requestAnimationFrame(() => {
+      const callbacks = pendingFrameCallbacks.slice()
+      isFrameScheduled = false
+      pendingFrameCallbacks = []
+      let hasError = false
+      let error
+      for (let i = 0; i < callbacks.length; i++) {
+        try {
+          callbacks[i]()
+        } catch (e) {
+          hasError = true
+          error = e
+        }
+      }
+      if (hasError) {
+        throw error
+      }
+    })
+  }
+}