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 {DimensionValue, Pressable, View} from 'react-native'
|
||||||
import Animated, {AnimatedRef, useAnimatedRef} from 'react-native-reanimated'
|
import Animated, {AnimatedRef, useAnimatedRef} from 'react-native-reanimated'
|
||||||
import {Image} from 'expo-image'
|
import {Image} from 'expo-image'
|
||||||
@@ -79,15 +79,19 @@ export function AutoSizedImage({
|
|||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
const largeAlt = useLargeAltBadgeEnabled()
|
const largeAlt = useLargeAltBadgeEnabled()
|
||||||
const containerRef = useAnimatedRef()
|
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
|
let aspectRatio: number | undefined
|
||||||
|
const dims = image.aspectRatio
|
||||||
if (dims) {
|
if (dims) {
|
||||||
aspectRatio = dims.width / dims.height
|
aspectRatio = dims.width / dims.height
|
||||||
if (Number.isNaN(aspectRatio)) {
|
if (Number.isNaN(aspectRatio)) {
|
||||||
aspectRatio = undefined
|
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
|
let constrained: number | undefined
|
||||||
@@ -113,13 +117,12 @@ export function AutoSizedImage({
|
|||||||
accessibilityIgnoresInvertColors
|
accessibilityIgnoresInvertColors
|
||||||
accessibilityLabel={image.alt}
|
accessibilityLabel={image.alt}
|
||||||
accessibilityHint=""
|
accessibilityHint=""
|
||||||
onLoad={
|
onLoad={e => {
|
||||||
fetchedDims
|
fetchedDimsRef.current = {
|
||||||
? undefined
|
width: e.source.width,
|
||||||
: e => {
|
height: e.source.height,
|
||||||
setFetchedDims({width: e.source.width, height: e.source.height})
|
}
|
||||||
}
|
}}
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
<MediaInsetBorder />
|
<MediaInsetBorder />
|
||||||
|
|
||||||
@@ -191,7 +194,7 @@ export function AutoSizedImage({
|
|||||||
if (cropDisabled) {
|
if (cropDisabled) {
|
||||||
return (
|
return (
|
||||||
<Pressable
|
<Pressable
|
||||||
onPress={() => onPress?.(containerRef, fetchedDims)}
|
onPress={() => onPress?.(containerRef, fetchedDimsRef.current)}
|
||||||
onLongPress={onLongPress}
|
onLongPress={onLongPress}
|
||||||
onPressIn={onPressIn}
|
onPressIn={onPressIn}
|
||||||
// alt here is what screen readers actually use
|
// alt here is what screen readers actually use
|
||||||
@@ -213,7 +216,7 @@ export function AutoSizedImage({
|
|||||||
fullBleed={crop === 'square'}
|
fullBleed={crop === 'square'}
|
||||||
aspectRatio={constrained ?? 1}>
|
aspectRatio={constrained ?? 1}>
|
||||||
<Pressable
|
<Pressable
|
||||||
onPress={() => onPress?.(containerRef, fetchedDims)}
|
onPress={() => onPress?.(containerRef, fetchedDimsRef.current)}
|
||||||
onLongPress={onLongPress}
|
onLongPress={onLongPress}
|
||||||
onPressIn={onPressIn}
|
onPressIn={onPressIn}
|
||||||
// alt here is what screen readers actually use
|
// alt here is what screen readers actually use
|
||||||
|
|||||||
Reference in New Issue
Block a user