Change lightbox to use Pager (#1666)

* Change lightbox to use Pager

* Fix crash issue on ios

---------

Co-authored-by: Paul Frazee <pfrazee@gmail.com>
This commit is contained in:
dan 2023-10-10 22:37:28 +01:00 committed by GitHub
parent aa085b0b14
commit 209d8b683c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 141 deletions

View file

@ -1,9 +1,8 @@
import React, {MutableRefObject, useState} from 'react'
import React, {useState} from 'react'
import {ActivityIndicator, Dimensions, StyleSheet} from 'react-native'
import {Image} from 'expo-image'
import Animated, {
measure,
runOnJS,
useAnimatedRef,
useAnimatedStyle,
@ -12,11 +11,7 @@ import Animated, {
withDecay,
withSpring,
} from 'react-native-reanimated'
import {
GestureDetector,
Gesture,
GestureType,
} from 'react-native-gesture-handler'
import {GestureDetector, Gesture} from 'react-native-gesture-handler'
import useImageDimensions from '../../hooks/useImageDimensions'
import {
createTransform,
@ -40,7 +35,6 @@ type Props = {
imageSrc: ImageSource
onRequestClose: () => void
onZoom: (isZoomed: boolean) => void
pinchGestureRef: MutableRefObject<GestureType | undefined>
isScrollViewBeingDragged: boolean
}
const ImageItem = ({
@ -48,7 +42,6 @@ const ImageItem = ({
onZoom,
onRequestClose,
isScrollViewBeingDragged,
pinchGestureRef,
}: Props) => {
const [isScaled, setIsScaled] = useState(false)
const [isLoaded, setIsLoaded] = useState(false)
@ -140,28 +133,7 @@ const ImageItem = ({
return [dx, dy]
}
// This is a hack.
// We need to disallow any gestures (and let the native parent scroll view scroll) while you're scrolling it.
// However, there is no great reliable way to coordinate this yet in RGNH.
// This "fake" manual gesture handler whenever you're trying to touch something while the parent scrollview is not at rest.
const consumeHScroll = Gesture.Manual().onTouchesDown((e, manager) => {
if (isScrollViewBeingDragged) {
// Steal the gesture (and do nothing, so native ScrollView does its thing).
manager.activate()
return
}
const measurement = measure(containerRef)
if (!measurement || measurement.pageX !== 0) {
// Steal the gesture (and do nothing, so native ScrollView does its thing).
manager.activate()
return
}
// Fail this "fake" gesture so that the gestures after it can proceed.
manager.fail()
})
const pinch = Gesture.Pinch()
.withRef(pinchGestureRef)
.onStart(e => {
pinchOrigin.value = {
x: e.focalX - SCREEN.width / 2,
@ -318,19 +290,22 @@ const ImageItem = ({
}
})
const composedGesture = isScrollViewBeingDragged
? // If the parent is not at rest, provide a no-op gesture.
Gesture.Manual()
: Gesture.Exclusive(
dismissSwipePan,
Gesture.Simultaneous(pinch, pan),
doubleTap,
)
const isLoading = !isLoaded || !imageDimensions
return (
<Animated.View ref={containerRef} style={styles.container}>
{isLoading && (
<ActivityIndicator size="small" color="#FFF" style={styles.loading} />
)}
<GestureDetector
gesture={Gesture.Exclusive(
consumeHScroll,
dismissSwipePan,
Gesture.Simultaneous(pinch, pan),
doubleTap,
)}>
<GestureDetector gesture={composedGesture}>
<AnimatedImage
source={imageSrc}
contentFit="contain"

View file

@ -6,7 +6,7 @@
*
*/
import React, {MutableRefObject, useCallback, useState} from 'react'
import React, {useCallback, useState} from 'react'
import {
Dimensions,
@ -25,7 +25,6 @@ import Animated, {
useAnimatedStyle,
useSharedValue,
} from 'react-native-reanimated'
import {GestureType} from 'react-native-gesture-handler'
import useImageDimensions from '../../hooks/useImageDimensions'
@ -43,7 +42,6 @@ type Props = {
imageSrc: ImageSource
onRequestClose: () => void
onZoom: (scaled: boolean) => void
pinchGestureRef: MutableRefObject<GestureType>
isScrollViewBeingDragged: boolean
}
@ -145,7 +143,7 @@ const ImageItem = ({imageSrc, onZoom, onRequestClose}: Props) => {
accessibilityHint="">
<AnimatedImage
contentFit="contain"
source={imageSrc}
source={{uri: imageSrc.uri}}
style={[styles.image, animatedStyle]}
onLoad={() => setLoaded(true)}
/>

View file

@ -1,15 +1,13 @@
// default implementation fallback for web
import React, {MutableRefObject} from 'react'
import React from 'react'
import {View} from 'react-native'
import {GestureType} from 'react-native-gesture-handler'
import {ImageSource} from '../../@types'
type Props = {
imageSrc: ImageSource
onRequestClose: () => void
onZoom: (scaled: boolean) => void
pinchGestureRef: MutableRefObject<GestureType | undefined>
isScrollViewBeingDragged: boolean
}