diff options
author | dan <dan.abramov@gmail.com> | 2024-11-28 16:55:05 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-28 16:55:05 +0000 |
commit | d08ce0d473374c0720d018e8fc8ed550ed32544a (patch) | |
tree | d564b58ea931538d23897c7b2ce8b69ac54c8580 /src/view/com/lightbox/ImageViewing/index.tsx | |
parent | 0aee6390fa8faad22608bbc2b0b4352c2af0a2f9 (diff) | |
download | voidsky-d08ce0d473374c0720d018e8fc8ed550ed32544a.tar.zst |
Fix stuck lightbox (#6816)
* Fix lightbox getting stuck by fixing rAF order If you spam opening lightbox too fast, the effect that calls rAF will clean up and set up again midflight. Unfortunately, due to rAF order being unreliable, it may fire in reverse order, causing "open, open, close" instead of "open, close, open", so it would get stuck closed. This fixes the rAF order. * Don't allow opening another lightbox while it's open
Diffstat (limited to 'src/view/com/lightbox/ImageViewing/index.tsx')
-rw-r--r-- | src/view/com/lightbox/ImageViewing/index.tsx | 33 |
1 files changed, 31 insertions, 2 deletions
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 + } + }) + } +} |