diff options
author | Paul Frazee <pfrazee@gmail.com> | 2023-03-21 12:59:10 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-21 12:59:10 -0500 |
commit | 858d4c8c8811ca8e16bffe3bfe0d541e576177ec (patch) | |
tree | 8199e1029edb7161c34fb59806399c30fcdd61a3 /src/view/com/util/images/AutoSizedImage.tsx | |
parent | c1d454b7cfe6a7ec107b39483df9cb0fb64e1c76 (diff) | |
download | voidsky-858d4c8c8811ca8e16bffe3bfe0d541e576177ec.tar.zst |
* Introduce an image sizes cache to improve feed layouts (close #213) * Clear out resolved promises from the image cache
Diffstat (limited to 'src/view/com/util/images/AutoSizedImage.tsx')
-rw-r--r-- | src/view/com/util/images/AutoSizedImage.tsx | 56 |
1 files changed, 39 insertions, 17 deletions
diff --git a/src/view/com/util/images/AutoSizedImage.tsx b/src/view/com/util/images/AutoSizedImage.tsx index 0443c7be4..24dbe6a52 100644 --- a/src/view/com/util/images/AutoSizedImage.tsx +++ b/src/view/com/util/images/AutoSizedImage.tsx @@ -1,7 +1,15 @@ import React from 'react' -import {StyleProp, StyleSheet, TouchableOpacity, ViewStyle} from 'react-native' -import Image, {OnLoadEvent} from 'view/com/util/images/Image' +import { + Image, + StyleProp, + StyleSheet, + TouchableOpacity, + ViewStyle, +} from 'react-native' +// import Image from 'view/com/util/images/Image' import {clamp} from 'lib/numbers' +import {useStores} from 'state/index' +import {Dim} from 'lib/media/manip' export const DELAY_PRESS_IN = 500 const MIN_ASPECT_RATIO = 0.33 // 1/3 @@ -22,16 +30,27 @@ export function AutoSizedImage({ style?: StyleProp<ViewStyle> children?: React.ReactNode }) { - const [aspectRatio, setAspectRatio] = React.useState<number>(1) - const onLoad = (e: OnLoadEvent) => { - setAspectRatio( - clamp( - e.nativeEvent.width / e.nativeEvent.height, - MIN_ASPECT_RATIO, - MAX_ASPECT_RATIO, - ), - ) - } + const store = useStores() + const [dim, setDim] = React.useState<Dim | undefined>( + store.imageSizes.get(uri), + ) + const [aspectRatio, setAspectRatio] = React.useState<number>( + dim ? calc(dim) : 1, + ) + React.useEffect(() => { + let aborted = false + if (dim) { + return + } + store.imageSizes.fetch(uri).then(newDim => { + if (aborted) { + return + } + setDim(newDim) + setAspectRatio(calc(newDim)) + }) + }, [dim, setDim, setAspectRatio, store, uri]) + return ( <TouchableOpacity onPress={onPress} @@ -39,16 +58,19 @@ export function AutoSizedImage({ onPressIn={onPressIn} delayPressIn={DELAY_PRESS_IN} style={[styles.container, style]}> - <Image - style={[styles.image, {aspectRatio}]} - source={{uri}} - onLoad={onLoad} - /> + <Image style={[styles.image, {aspectRatio}]} source={{uri}} /> {children} </TouchableOpacity> ) } +function calc(dim: Dim) { + if (dim.width === 0 || dim.height === 0) { + return 1 + } + return clamp(dim.width / dim.height, MIN_ASPECT_RATIO, MAX_ASPECT_RATIO) +} + const styles = StyleSheet.create({ container: { overflow: 'hidden', |