Fix layout jumps for images (#6474)
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user