about summary refs log tree commit diff
path: root/src/view/com/util/images/AutoSizedImage.tsx
diff options
context:
space:
mode:
authorPaul Frazee <pfrazee@gmail.com>2023-03-21 12:59:10 -0500
committerGitHub <noreply@github.com>2023-03-21 12:59:10 -0500
commit858d4c8c8811ca8e16bffe3bfe0d541e576177ec (patch)
tree8199e1029edb7161c34fb59806399c30fcdd61a3 /src/view/com/util/images/AutoSizedImage.tsx
parentc1d454b7cfe6a7ec107b39483df9cb0fb64e1c76 (diff)
downloadvoidsky-858d4c8c8811ca8e16bffe3bfe0d541e576177ec.tar.zst
Introduce an image sizes cache to improve feed layouts (close #213) (#335)
* 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.tsx56
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',