Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

authored by

dan and committed by
GitHub
d08ce0d4 0aee6390

+40 -3
+9 -1
src/state/lightbox.tsx
··· 31 31 32 32 const openLightbox = useNonReactiveCallback( 33 33 (lightbox: Omit<Lightbox, 'id'>) => { 34 - setActiveLightbox({...lightbox, id: nanoid()}) 34 + setActiveLightbox(prevLightbox => { 35 + if (prevLightbox) { 36 + // Ignore duplicate open requests. If it's already open, 37 + // the user has to explicitly close the previous one first. 38 + return prevLightbox 39 + } else { 40 + return {...lightbox, id: nanoid()} 41 + } 42 + }) 35 43 }, 36 44 ) 37 45
+31 -2
src/view/com/lightbox/ImageViewing/index.tsx
··· 111 111 ) 112 112 113 113 // https://github.com/software-mansion/react-native-reanimated/issues/6677 114 - requestAnimationFrame(() => { 114 + rAF_FIXED(() => { 115 115 openProgress.set(() => 116 116 canAnimate ? withClampedSpring(1, SLOW_SPRING) : 1, 117 117 ) 118 118 }) 119 119 return () => { 120 120 // https://github.com/software-mansion/react-native-reanimated/issues/6677 121 - requestAnimationFrame(() => { 121 + rAF_FIXED(() => { 122 122 openProgress.set(() => 123 123 canAnimate ? withClampedSpring(0, SLOW_SPRING) : 0, 124 124 ) ··· 752 752 'worklet' 753 753 return withSpring(value, {...config, overshootClamping: true}) 754 754 } 755 + 756 + // We have to do this because we can't trust RN's rAF to fire in order. 757 + // https://github.com/facebook/react-native/issues/48005 758 + let isFrameScheduled = false 759 + let pendingFrameCallbacks: Array<() => void> = [] 760 + function rAF_FIXED(callback: () => void) { 761 + pendingFrameCallbacks.push(callback) 762 + if (!isFrameScheduled) { 763 + isFrameScheduled = true 764 + requestAnimationFrame(() => { 765 + const callbacks = pendingFrameCallbacks.slice() 766 + isFrameScheduled = false 767 + pendingFrameCallbacks = [] 768 + let hasError = false 769 + let error 770 + for (let i = 0; i < callbacks.length; i++) { 771 + try { 772 + callbacks[i]() 773 + } catch (e) { 774 + hasError = true 775 + error = e 776 + } 777 + } 778 + if (hasError) { 779 + throw error 780 + } 781 + }) 782 + } 783 + }