my fork of the bluesky client

Fix layout jumps for images (#6474)

authored by danabra.mov and committed by

GitHub ec973522 924f1e0e

+15 -12
+15 -12
src/view/com/util/images/AutoSizedImage.tsx
··· 1 - import React from 'react' 1 + import React, {useRef} from 'react' 2 2 import {DimensionValue, Pressable, View} from 'react-native' 3 3 import Animated, {AnimatedRef, useAnimatedRef} from 'react-native-reanimated' 4 4 import {Image} from 'expo-image' ··· 79 79 const {_} = useLingui() 80 80 const largeAlt = useLargeAltBadgeEnabled() 81 81 const containerRef = useAnimatedRef() 82 + const fetchedDimsRef = useRef<{width: number; height: number} | null>(null) 82 83 83 - const [fetchedDims, setFetchedDims] = React.useState<Dimensions | null>(null) 84 - const dims = fetchedDims ?? image.aspectRatio 85 84 let aspectRatio: number | undefined 85 + const dims = image.aspectRatio 86 86 if (dims) { 87 87 aspectRatio = dims.width / dims.height 88 88 if (Number.isNaN(aspectRatio)) { 89 89 aspectRatio = undefined 90 90 } 91 + } else { 92 + // If we don't know it synchronously, treat it like a square. 93 + // We won't use fetched dimensions to avoid a layout shift. 94 + aspectRatio = 1 91 95 } 92 96 93 97 let constrained: number | undefined ··· 113 117 accessibilityIgnoresInvertColors 114 118 accessibilityLabel={image.alt} 115 119 accessibilityHint="" 116 - onLoad={ 117 - fetchedDims 118 - ? undefined 119 - : e => { 120 - setFetchedDims({width: e.source.width, height: e.source.height}) 121 - } 122 - } 120 + onLoad={e => { 121 + fetchedDimsRef.current = { 122 + width: e.source.width, 123 + height: e.source.height, 124 + } 125 + }} 123 126 /> 124 127 <MediaInsetBorder /> 125 128 ··· 191 194 if (cropDisabled) { 192 195 return ( 193 196 <Pressable 194 - onPress={() => onPress?.(containerRef, fetchedDims)} 197 + onPress={() => onPress?.(containerRef, fetchedDimsRef.current)} 195 198 onLongPress={onLongPress} 196 199 onPressIn={onPressIn} 197 200 // alt here is what screen readers actually use ··· 213 216 fullBleed={crop === 'square'} 214 217 aspectRatio={constrained ?? 1}> 215 218 <Pressable 216 - onPress={() => onPress?.(containerRef, fetchedDims)} 219 + onPress={() => onPress?.(containerRef, fetchedDimsRef.current)} 217 220 onLongPress={onLongPress} 218 221 onPressIn={onPressIn} 219 222 // alt here is what screen readers actually use