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
This commit is contained in:
@@ -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 (
|
return (
|
||||||
<Animated.View style={[styles.container, containerStyle]}>
|
<Animated.View style={[styles.container, containerStyle]}>
|
||||||
<Animated.View
|
<Animated.View
|
||||||
@@ -256,12 +273,23 @@ function LightboxImage({
|
|||||||
.maxPointers(1)
|
.maxPointers(1)
|
||||||
.onUpdate(e => {
|
.onUpdate(e => {
|
||||||
'worklet'
|
'worklet'
|
||||||
|
if (isFlyingAway.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
dismissSwipeTranslateY.value = e.translationY
|
dismissSwipeTranslateY.value = e.translationY
|
||||||
})
|
})
|
||||||
.onEnd(e => {
|
.onEnd(e => {
|
||||||
'worklet'
|
'worklet'
|
||||||
|
if (isFlyingAway.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
if (Math.abs(e.velocityY) > 1000) {
|
if (Math.abs(e.velocityY) > 1000) {
|
||||||
isFlyingAway.value = true
|
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({
|
dismissSwipeTranslateY.value = withDecay({
|
||||||
velocity: e.velocityY,
|
velocity: e.velocityY,
|
||||||
velocityFactor: Math.max(3000 / Math.abs(e.velocityY), 1), // Speed up if it's too slow.
|
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(() => {
|
const imageStyle = useAnimatedStyle(() => {
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user