From 5743c4d148c5bf6e5a9557fa94e30ef1c3cfa741 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Sun, 3 Nov 2024 02:09:30 +0000 Subject: [PATCH] Make iOS-unreliable state Android-only We didn't really need the only existing xplat usage of it (but it *was* causing bugs). --- .../components/ImageItem/ImageItem.android.tsx | 6 +++--- .../components/ImageItem/ImageItem.ios.tsx | 2 +- .../components/ImageItem/ImageItem.tsx | 2 +- src/view/com/lightbox/ImageViewing/index.tsx | 18 +++++++++++------- 4 files changed, 16 insertions(+), 12 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 9d0ea67007..e5284faa6a 100644 --- a/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.android.tsx +++ b/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.android.tsx @@ -44,7 +44,7 @@ type Props = { onRequestClose: () => void onTap: () => void onZoom: (isZoomed: boolean) => void - isScrollViewBeingDragged: boolean + isPagingAndroid: boolean showControls: boolean dismissSwipePan: PanGesture } @@ -52,7 +52,7 @@ const ImageItem = ({ imageSrc, onTap, onZoom, - isScrollViewBeingDragged, + isPagingAndroid, dismissSwipePan, }: Props) => { const [isScaled, setIsScaled] = useState(false) @@ -282,7 +282,7 @@ const ImageItem = ({ committedTransform.value = withClampedSpring(finalTransform) }) - const composedGesture = isScrollViewBeingDragged + const composedGesture = isPagingAndroid ? // If the parent is not at rest, provide a no-op gesture. Gesture.Manual() : Gesture.Exclusive( 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 daad19bef3..9c09382701 100644 --- a/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.ios.tsx +++ b/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.ios.tsx @@ -29,7 +29,7 @@ type Props = { onRequestClose: () => void onTap: () => void onZoom: (scaled: boolean) => void - isScrollViewBeingDragged: boolean + isPagingAndroid: boolean // Not available on iOS showControls: boolean dismissSwipePan: PanGesture | null } diff --git a/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.tsx b/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.tsx index a08abc18b4..57b6f029cb 100644 --- a/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.tsx +++ b/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.tsx @@ -11,7 +11,7 @@ type Props = { onRequestClose: () => void onTap: () => void onZoom: (scaled: boolean) => void - isScrollViewBeingDragged: boolean + isPagingAndroid: boolean showControls: boolean dismissSwipePan: PanGesture | null } diff --git a/src/view/com/lightbox/ImageViewing/index.tsx b/src/view/com/lightbox/ImageViewing/index.tsx index ee402bd7ba..df8f7df5df 100644 --- a/src/view/com/lightbox/ImageViewing/index.tsx +++ b/src/view/com/lightbox/ImageViewing/index.tsx @@ -37,7 +37,7 @@ import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {Trans} from '@lingui/macro' import {colors, s} from '#/lib/styles' -import {isIOS} from '#/platform/detection' +import {isAndroid, isIOS} from '#/platform/detection' import {Lightbox} from '#/state/lightbox' import {Button} from '#/view/com/util/forms/Button' import {Text} from '#/view/com/util/text/Text' @@ -68,7 +68,7 @@ function ImageViewing({ }) { const {images, index: initialImageIndex} = lightbox const [isScaled, setIsScaled] = useState(false) - const [isDragging, setIsDragging] = useState(false) + const [isPagingAndroid, setIsPagingAndroid] = useState(false) const [imageIndex, setImageIndex] = useState(initialImageIndex) const [showControls, setShowControls] = useState(true) const dismissSwipeTranslateY = useSharedValue(0) @@ -211,7 +211,13 @@ function ImageViewing({ setIsScaled(false) }} onPageScrollStateChanged={e => { - setIsDragging(e.nativeEvent.pageScrollState !== 'idle') + if (isAndroid) { + // This condition isn't reliable on iOS (the pager may send + // events out of order if you spam it with vertical pans in + // the middle of deceleration). However, we only need this + // variable for Android anyway, so let's make that explicit. + setIsPagingAndroid(e.nativeEvent.pageScrollState !== 'idle') + } }} overdrag={true} style={styles.pager}> @@ -224,11 +230,9 @@ function ImageViewing({ onZoom={onZoom} imageSrc={imageSrc} onRequestClose={onRequestClose} - isScrollViewBeingDragged={isDragging} + isPagingAndroid={isPagingAndroid} showControls={showControls} - dismissSwipePan={ - imageIndex === i && !isDragging ? dismissSwipePan : null - } + dismissSwipePan={imageIndex === i ? dismissSwipePan : null} /> ))}