From ad3644e66819441e48b63c7758aaf869bfd98fb0 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Fri, 29 Sep 2023 16:58:46 +0100 Subject: [PATCH] Fix gallery view --- .../ImageItem/ImageItem.android.tsx | 34 ++++++++++++++- src/view/com/lightbox/ImageViewing/index.tsx | 43 +++++++++++++++---- 2 files changed, 67 insertions(+), 10 deletions(-) diff --git a/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.android.tsx b/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.android.tsx index 3385933ca4..f2155c4367 100644 --- a/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.android.tsx +++ b/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.android.tsx @@ -10,7 +10,9 @@ import { } from 'react-native' import {Image} from 'expo-image' import Animated, { + runOnJS, useAnimatedStyle, + useAnimatedReaction, useDerivedValue, useSharedValue, } from 'react-native-reanimated' @@ -38,7 +40,7 @@ type Props = { doubleTapToZoomEnabled?: boolean } - type Matrix3 = readonly [ + type Matrix3 = [ number, number, number, @@ -106,6 +108,14 @@ function prependPinch(t, scale, origin, translation) { prependTranslate(t, -origin.x, -origin.y); } +function applyRounding(t) { + 'worklet' + t[2] = Math.round(t[2]) + t[5] = Math.round(t[5]) + t[0] = Math.round(t[0] * 200) / 200; + t[4] = Math.round(t[0] * 200) / 200; +} + function toStyle(t) { "worklet"; const [translateX, translateY, scale] = readTransform(t) @@ -154,6 +164,7 @@ const ImageItem = ({ swipeToCloseEnabled = true, doubleTapToZoomEnabled = true, }: Props) => { + const [isScaled, setIsScaled] = useState(false) const imageDimensions = useImageDimensions(imageSrc) const committedTransform = useSharedValue(initialTransform) const pinchOrigin = useSharedValue({ x: 0, y: 0 }) @@ -161,6 +172,24 @@ const ImageItem = ({ const pinchTranslation = useSharedValue({ x: 0, y: 0 }) const panTranslation = useSharedValue({ x: 0, y: 0 }) + useAnimatedReaction( + () => { + if (pinchScale.value !== 1) { + return true; + } + const [,,scale] = readTransform(committedTransform.value) + if (scale !== 1) { + return true; + } + return false; + }, + (isScaledNow, wasScaledBefore) => { + if (isScaledNow !== wasScaledBefore) { + runOnJS(setIsScaled)(isScaledNow) + } + } + ) + const animatedStyle = useAnimatedStyle(() => { let t = createTransform(); prependPan(t, panTranslation.value); @@ -210,6 +239,7 @@ const ImageItem = ({ let t = createTransform(); prependPinch(t, pinchScale.value, pinchOrigin.value, pinchTranslation.value) prependTransform(t, committedTransform.value); + applyRounding(t) committedTransform.value = t pinchScale.value = 1; pinchOrigin.value = { x: 0, y: 0 }; @@ -218,6 +248,7 @@ const ImageItem = ({ const pan = Gesture.Pan() .averageTouches(true) + .enabled(isScaled) .onChange((e) => { if (!imageDimensions) { return; @@ -232,6 +263,7 @@ const ImageItem = ({ let t = createTransform(); prependPan(t, panTranslation.value) prependTransform(t, committedTransform.value); + applyRounding(t) committedTransform.value = t panTranslation.value = { x: 0, y: 0 }; }); diff --git a/src/view/com/lightbox/ImageViewing/index.tsx b/src/view/com/lightbox/ImageViewing/index.tsx index 8583047fca..1a64fb3afb 100644 --- a/src/view/com/lightbox/ImageViewing/index.tsx +++ b/src/view/com/lightbox/ImageViewing/index.tsx @@ -129,15 +129,40 @@ function ImageViewing({ )} - {/* TODO: show gallery again */} - images[index]} + getItemCount={() => images.length} + getItemLayout={(_, index) => ({ + length: SCREEN_WIDTH, + offset: SCREEN_WIDTH * index, + index, + })} + renderItem={({item: imageSrc}) => ( + + )} + onMomentumScrollEnd={onScroll} + //@ts-ignore + keyExtractor={(imageSrc, index) => + keyExtractor + ? keyExtractor(imageSrc, index) + : typeof imageSrc === 'number' + ? `${imageSrc}` + : imageSrc.uri + } /> {typeof FooterComponent !== 'undefined' && (