diff options
Diffstat (limited to 'src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.ios.tsx')
-rw-r--r-- | src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.ios.tsx | 95 |
1 files changed, 44 insertions, 51 deletions
diff --git a/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.ios.tsx b/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.ios.tsx index a17d4fe66..b4bbfb4d5 100644 --- a/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.ios.tsx +++ b/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.ios.tsx @@ -7,26 +7,27 @@ */ import React, {useState} from 'react' -import {ActivityIndicator, StyleSheet, View} from 'react-native' -import {Gesture, GestureDetector} from 'react-native-gesture-handler' +import {ActivityIndicator, StyleProp, StyleSheet, View} from 'react-native' +import { + Gesture, + GestureDetector, + PanGesture, +} from 'react-native-gesture-handler' import Animated, { AnimatedRef, - interpolate, measure, runOnJS, useAnimatedRef, useAnimatedStyle, - useSharedValue, } from 'react-native-reanimated' import {useSafeAreaFrame} from 'react-native-safe-area-context' -import {Image} from 'expo-image' +import {Image, ImageStyle} from 'expo-image' import {useAnimatedScrollHandler} from '#/lib/hooks/useAnimatedScrollHandler_FIXED' -import {useImageDimensions} from '#/lib/media/image-sizes' -import {ImageSource} from '../../@types' +import {Dimensions as ImageDimensions, ImageSource} from '../../@types' + +const AnimatedImage = Animated.createAnimatedComponent(Image) -const SWIPE_CLOSE_OFFSET = 75 -const SWIPE_CLOSE_VELOCITY = 1 const MAX_ORIGINAL_IMAGE_ZOOM = 2 const MIN_SCREEN_ZOOM = 2 @@ -38,24 +39,26 @@ type Props = { isScrollViewBeingDragged: boolean showControls: boolean safeAreaRef: AnimatedRef<View> + imageAspect: number | undefined + imageDimensions: ImageDimensions | undefined + imageStyle: StyleProp<ImageStyle> + dismissSwipePan: PanGesture } const ImageItem = ({ imageSrc, onTap, onZoom, - onRequestClose, showControls, safeAreaRef, + imageAspect, + imageDimensions, + imageStyle, + dismissSwipePan, }: Props) => { const scrollViewRef = useAnimatedRef<Animated.ScrollView>() - const translationY = useSharedValue(0) const [scaled, setScaled] = useState(false) const screenSizeDelayedForJSThreadOnly = useSafeAreaFrame() - const [imageAspect, imageDimensions] = useImageDimensions({ - src: imageSrc.uri, - knownDimensions: imageSrc.dimensions, - }) const maxZoomScale = Math.max( MIN_SCREEN_ZOOM, imageDimensions @@ -65,33 +68,21 @@ const ImageItem = ({ ) const animatedStyle = useAnimatedStyle(() => { + const screenSize = measure(safeAreaRef) ?? screenSizeDelayedForJSThreadOnly return { - flex: 1, - opacity: interpolate( - translationY.value, - [-SWIPE_CLOSE_OFFSET, 0, SWIPE_CLOSE_OFFSET], - [0.5, 1, 0.5], - ), + width: screenSize.width, + maxHeight: screenSize.height, + alignSelf: 'center', + aspectRatio: imageAspect, } }) const scrollHandler = useAnimatedScrollHandler({ onScroll(e) { const nextIsScaled = e.zoomScale > 1 - translationY.value = nextIsScaled ? 0 : e.contentOffset.y - if (scaled !== nextIsScaled) { - runOnJS(handleZoom)(nextIsScaled) - } - }, - onEndDrag(e) { - const velocityY = e.velocity?.y ?? 0 - const nextIsScaled = e.zoomScale > 1 if (scaled !== nextIsScaled) { runOnJS(handleZoom)(nextIsScaled) } - if (!nextIsScaled && Math.abs(velocityY) > SWIPE_CLOSE_VELOCITY) { - runOnJS(onRequestClose)() - } }, }) @@ -146,7 +137,11 @@ const ImageItem = ({ runOnJS(zoomTo)(nextZoomRect) }) - const composedGesture = Gesture.Exclusive(doubleTap, singleTap) + const composedGesture = Gesture.Exclusive( + dismissSwipePan, + doubleTap, + singleTap, + ) return ( <GestureDetector gesture={composedGesture}> @@ -158,21 +153,22 @@ const ImageItem = ({ showsVerticalScrollIndicator={false} maximumZoomScale={maxZoomScale} onScroll={scrollHandler} - contentContainerStyle={styles.scrollContainer}> - <Animated.View style={animatedStyle}> - <ActivityIndicator size="small" color="#FFF" style={styles.loading} /> - <Image - contentFit="contain" - source={{uri: imageSrc.uri}} - placeholderContentFit="contain" - placeholder={{uri: imageSrc.thumbUri}} - style={styles.image} - accessibilityLabel={imageSrc.alt} - accessibilityHint="" - enableLiveTextInteraction={showControls && !scaled} - accessibilityIgnoresInvertColors - /> - </Animated.View> + bounces={scaled} + bouncesZoom={true} + style={imageStyle} + centerContent> + <ActivityIndicator size="small" color="#FFF" style={styles.loading} /> + <AnimatedImage + contentFit="contain" + source={{uri: imageSrc.uri}} + placeholderContentFit="contain" + placeholder={{uri: imageSrc.thumbUri}} + style={animatedStyle} + accessibilityLabel={imageSrc.alt} + accessibilityHint="" + enableLiveTextInteraction={showControls && !scaled} + accessibilityIgnoresInvertColors + /> </Animated.ScrollView> </GestureDetector> ) @@ -186,9 +182,6 @@ const styles = StyleSheet.create({ right: 0, bottom: 0, }, - scrollContainer: { - flex: 1, - }, image: { flex: 1, }, |