diff options
Diffstat (limited to 'src/view/com/util/images/AutoSizedImage.tsx')
-rw-r--r-- | src/view/com/util/images/AutoSizedImage.tsx | 40 |
1 files changed, 20 insertions, 20 deletions
diff --git a/src/view/com/util/images/AutoSizedImage.tsx b/src/view/com/util/images/AutoSizedImage.tsx index fe8911e31..617b9bec4 100644 --- a/src/view/com/util/images/AutoSizedImage.tsx +++ b/src/view/com/util/images/AutoSizedImage.tsx @@ -1,11 +1,11 @@ -import React from 'react' +import React, {useRef} from 'react' import {DimensionValue, Pressable, View} from 'react-native' -import Animated, {AnimatedRef, useAnimatedRef} from 'react-native-reanimated' import {Image} from 'expo-image' import {AppBskyEmbedImages} from '@atproto/api' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' +import {HandleRef, useHandleRef} from '#/lib/hooks/useHandleRef' import type {Dimensions} from '#/lib/media/types' import {isNative} from '#/platform/detection' import {useLargeAltBadgeEnabled} from '#/state/preferences/large-alt-badge' @@ -68,26 +68,27 @@ export function AutoSizedImage({ image: AppBskyEmbedImages.ViewImage crop?: 'none' | 'square' | 'constrained' hideBadge?: boolean - onPress?: ( - containerRef: AnimatedRef<React.Component<{}, {}, any>>, - fetchedDims: Dimensions | null, - ) => void + onPress?: (containerRef: HandleRef, fetchedDims: Dimensions | null) => void onLongPress?: () => void onPressIn?: () => void }) { const t = useTheme() const {_} = useLingui() const largeAlt = useLargeAltBadgeEnabled() - const containerRef = useAnimatedRef() + const containerRef = useHandleRef() + const fetchedDimsRef = useRef<{width: number; height: number} | null>(null) - const [fetchedDims, setFetchedDims] = React.useState<Dimensions | null>(null) - const dims = fetchedDims ?? image.aspectRatio let aspectRatio: number | undefined + const dims = image.aspectRatio if (dims) { aspectRatio = dims.width / dims.height if (Number.isNaN(aspectRatio)) { aspectRatio = undefined } + } else { + // If we don't know it synchronously, treat it like a square. + // We won't use fetched dimensions to avoid a layout shift. + aspectRatio = 1 } let constrained: number | undefined @@ -105,7 +106,7 @@ export function AutoSizedImage({ const hasAlt = !!image.alt const contents = ( - <Animated.View ref={containerRef} collapsable={false} style={{flex: 1}}> + <View ref={containerRef} collapsable={false} style={{flex: 1}}> <Image style={[a.w_full, a.h_full]} source={image.thumb} @@ -113,13 +114,12 @@ export function AutoSizedImage({ accessibilityIgnoresInvertColors accessibilityLabel={image.alt} accessibilityHint="" - onLoad={ - fetchedDims - ? undefined - : e => { - setFetchedDims({width: e.source.width, height: e.source.height}) - } - } + onLoad={e => { + fetchedDimsRef.current = { + width: e.source.width, + height: e.source.height, + } + }} /> <MediaInsetBorder /> @@ -185,13 +185,13 @@ export function AutoSizedImage({ )} </View> ) : null} - </Animated.View> + </View> ) if (cropDisabled) { return ( <Pressable - onPress={() => onPress?.(containerRef, fetchedDims)} + onPress={() => onPress?.(containerRef, fetchedDimsRef.current)} onLongPress={onLongPress} onPressIn={onPressIn} // alt here is what screen readers actually use @@ -213,7 +213,7 @@ export function AutoSizedImage({ fullBleed={crop === 'square'} aspectRatio={constrained ?? 1}> <Pressable - onPress={() => onPress?.(containerRef, fetchedDims)} + onPress={() => onPress?.(containerRef, fetchedDimsRef.current)} onLongPress={onLongPress} onPressIn={onPressIn} // alt here is what screen readers actually use |