From d8eaf8b06cd5519c83bbb957fe6f596cb610128b Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Sun, 3 Nov 2024 05:09:07 +0000 Subject: [PATCH] Factor props upwards Also fix handling of missing aspectRatio --- .../ImageItem/ImageItem.android.tsx | 33 ++++++------------- .../components/ImageItem/ImageItem.ios.tsx | 30 +++++------------ .../components/ImageItem/ImageItem.tsx | 4 ++- src/view/com/lightbox/ImageViewing/index.tsx | 19 +++++++---- 4 files changed, 34 insertions(+), 52 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 a063f1f973..d6bd73520f 100644 --- a/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.android.tsx +++ b/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.android.tsx @@ -20,7 +20,6 @@ import Animated, { } from 'react-native-reanimated' import {Image, ImageStyle} from 'expo-image' -import {useImageDimensions} from '#/lib/media/image-sizes' import type {Dimensions as ImageDimensions, ImageSource} from '../../@types' import { applyRounding, @@ -55,6 +54,8 @@ type Props = { showControls: boolean dismissSwipePan: PanGesture imageStyle: StyleProp + imageAspect: number | undefined + dimensions: ImageDimensions | undefined } const ImageItem = ({ @@ -64,12 +65,10 @@ const ImageItem = ({ isPagingAndroid, dismissSwipePan, imageStyle, + imageAspect, + dimensions, }: Props) => { const [isScaled, setIsScaled] = useState(false) - const [imageAspect, imageDimensions] = useImageDimensions({ - src: imageSrc.uri, - knownDimensions: imageSrc.dimensions, - }) const committedTransform = useSharedValue(initialTransform) const panTranslation = useSharedValue({x: 0, y: 0}) const pinchOrigin = useSharedValue({x: 0, y: 0}) @@ -155,14 +154,14 @@ const ImageItem = ({ }) .onChange(e => { 'worklet' - if (!imageDimensions) { + if (!dimensions) { return } // Don't let the picture zoom in so close that it gets blurry. // Also, like in stock Android apps, don't let the user zoom out further than 1:1. const [, , committedScale] = readTransform(committedTransform.value) const maxCommittedScale = - (imageDimensions.width / SCREEN.width) * MAX_ORIGINAL_IMAGE_ZOOM + (dimensions.width / SCREEN.width) * MAX_ORIGINAL_IMAGE_ZOOM const minPinchScale = 1 / committedScale const maxPinchScale = maxCommittedScale / committedScale const nextPinchScale = Math.min( @@ -211,7 +210,7 @@ const ImageItem = ({ .minPointers(isScaled ? 1 : 2) .onChange(e => { 'worklet' - if (!imageDimensions) { + if (!dimensions) { return } const nextPanTranslation = {x: e.translationX, y: e.translationY} @@ -259,7 +258,7 @@ const ImageItem = ({ .numberOfTaps(2) .onEnd(e => { 'worklet' - if (!imageDimensions || !imageAspect) { + if (!dimensions || !imageAspect) { return } const [, , committedScale] = readTransform(committedTransform.value) @@ -279,7 +278,7 @@ const ImageItem = ({ ) // But don't zoom in so close that the picture gets blurry. const maxScale = - (imageDimensions.width / SCREEN.width) * MAX_ORIGINAL_IMAGE_ZOOM + (dimensions.width / SCREEN.width) * MAX_ORIGINAL_IMAGE_ZOOM const scale = Math.min(candidateScale, maxScale) // Calculate where we would be if the user pinched into the double tapped point. @@ -321,19 +320,7 @@ const ImageItem = ({ source={{uri: imageSrc.uri}} placeholderContentFit="cover" placeholder={{uri: imageSrc.thumbUri}} - style={[ - { - width: SCREEN.width, - height: imageAspect ? SCREEN.width / imageAspect : undefined, - borderRadius: - imageSrc.type === 'circle-avi' - ? SCREEN.width / 2 - : imageSrc.type === 'rect-avi' - ? 20 - : 0, - }, - imageStyle, - ]} + style={imageStyle} accessibilityLabel={imageSrc.alt} accessibilityHint="" accessibilityIgnoresInvertColors 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 01fd416f6b..9a635d83ee 100644 --- a/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.ios.tsx +++ b/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.ios.tsx @@ -22,8 +22,7 @@ import Animated, {runOnJS, useAnimatedRef} from 'react-native-reanimated' 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) @@ -40,25 +39,24 @@ type Props = { showControls: boolean dismissSwipePan: PanGesture | null imageStyle: StyleProp + imageAspect: number | undefined + dimensions: ImageDimensions | undefined } const ImageItem = ({ imageSrc, + dimensions, onTap, onZoom, showControls, dismissSwipePan, imageStyle, + imageAspect, }: Props) => { const scrollViewRef = useAnimatedRef() - const [scaled, setScaled] = useState(false) - const [imageAspect, imageDimensions] = useImageDimensions({ - src: imageSrc.uri, - knownDimensions: imageSrc.dimensions, - }) - const maxZoomScale = imageDimensions - ? (imageDimensions.width / SCREEN.width) * MAX_ORIGINAL_IMAGE_ZOOM + const maxZoomScale = dimensions + ? (dimensions.width / SCREEN.width) * MAX_ORIGINAL_IMAGE_ZOOM : 1 const scrollHandler = useAnimatedScrollHandler({ @@ -158,19 +156,7 @@ const ImageItem = ({ source={{uri: imageSrc.uri}} placeholderContentFit="cover" placeholder={{uri: imageSrc.thumbUri}} - style={[ - { - width: SCREEN.width, - height: imageAspect ? SCREEN.width / imageAspect : undefined, - borderRadius: - imageSrc.type === 'circle-avi' - ? SCREEN.width / 2 - : imageSrc.type === 'rect-avi' - ? 20 - : 0, - }, - imageStyle, - ]} + style={imageStyle} accessibilityLabel={imageSrc.alt} accessibilityHint="" enableLiveTextInteraction={showControls && !scaled} diff --git a/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.tsx b/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.tsx index 05d26d772b..8c1ae6fc4e 100644 --- a/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.tsx +++ b/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.tsx @@ -5,7 +5,7 @@ import {StyleProp, View} from 'react-native' import {PanGesture} from 'react-native-gesture-handler' import {ImageStyle} from 'expo-image' -import {ImageSource} from '../../@types' +import {Dimensions as ImageDimensions, ImageSource} from '../../@types' type Props = { imageSrc: ImageSource @@ -16,6 +16,8 @@ type Props = { showControls: boolean dismissSwipePan: PanGesture | null imageStyle: StyleProp + imageAspect: number | undefined + dimensions: ImageDimensions | undefined } const ImageItem = (_props: Props) => { diff --git a/src/view/com/lightbox/ImageViewing/index.tsx b/src/view/com/lightbox/ImageViewing/index.tsx index 89822c500c..99af871777 100644 --- a/src/view/com/lightbox/ImageViewing/index.tsx +++ b/src/view/com/lightbox/ImageViewing/index.tsx @@ -38,6 +38,7 @@ import {Edge, SafeAreaView} from 'react-native-safe-area-context' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {Trans} from '@lingui/macro' +import {useImageDimensions} from '#/lib/media/image-sizes' import {colors, s} from '#/lib/styles' import {isAndroid, isIOS} from '#/platform/detection' import {Lightbox} from '#/state/lightbox' @@ -262,20 +263,22 @@ function LightboxPage({ dismissSwipeTranslateY: SharedValue dismissSwipePan: PanGesture }) { - const {thumbRect, dimensions} = imageSrc - const imageAspect = dimensions - ? dimensions.width / dimensions.height - : undefined + const {thumbRect, dimensions: knownDimensions, type} = imageSrc + const [imageAspect, dimensions] = useImageDimensions({ + src: imageSrc.uri, + knownDimensions, + }) + const finalWidth = SCREEN.width const finalHeight = imageAspect ? SCREEN.width / imageAspect : undefined const interpolation = useDerivedValue(() => { - if (isActive && thumbRect && dimensions && openProgress.value < 1) { + if (isActive && thumbRect && knownDimensions && openProgress.value < 1) { return interpolateTransform( openProgress.value, thumbRect, SCREEN, - dimensions, + knownDimensions, ) } const translateY = isActive ? dismissSwipeTranslateY.value : 0 @@ -299,6 +302,8 @@ function LightboxPage({ return { width, height, + borderRadius: + type === 'circle-avi' ? SCREEN.width / 2 : type === 'rect-avi' ? 20 : 0, } }) @@ -313,6 +318,8 @@ function LightboxPage({ showControls={showControls} dismissSwipePan={isActive ? dismissSwipePan : null} imageStyle={imageStyle} + imageAspect={imageAspect} + dimensions={dimensions} /> )