diff options
author | dan <dan.abramov@gmail.com> | 2024-11-18 21:42:32 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-18 21:42:32 +0000 |
commit | ec973522015b7a83262184f0775d04ef784f53ff (patch) | |
tree | 3d644a3c8ec7493602a66e3121c87e3168423181 /src/view/com/util/images/AutoSizedImage.tsx | |
parent | 924f1e0e7f097b38081256920c71ddcc3f4ec85f (diff) | |
download | voidsky-ec973522015b7a83262184f0775d04ef784f53ff.tar.zst |
Fix layout jumps for images (#6474)
Diffstat (limited to 'src/view/com/util/images/AutoSizedImage.tsx')
-rw-r--r-- | src/view/com/util/images/AutoSizedImage.tsx | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/src/view/com/util/images/AutoSizedImage.tsx b/src/view/com/util/images/AutoSizedImage.tsx index fe8911e31..0ecbb3597 100644 --- a/src/view/com/util/images/AutoSizedImage.tsx +++ b/src/view/com/util/images/AutoSizedImage.tsx @@ -1,4 +1,4 @@ -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' @@ -79,15 +79,19 @@ export function AutoSizedImage({ const {_} = useLingui() const largeAlt = useLargeAltBadgeEnabled() const containerRef = useAnimatedRef() + 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 @@ -113,13 +117,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 /> @@ -191,7 +194,7 @@ export function AutoSizedImage({ 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 +216,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 |