about summary refs log tree commit diff
path: root/src/view/com/util/images/AutoSizedImage.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/com/util/images/AutoSizedImage.tsx')
-rw-r--r--src/view/com/util/images/AutoSizedImage.tsx67
1 files changed, 30 insertions, 37 deletions
diff --git a/src/view/com/util/images/AutoSizedImage.tsx b/src/view/com/util/images/AutoSizedImage.tsx
index 21f6c529e..c26df8335 100644
--- a/src/view/com/util/images/AutoSizedImage.tsx
+++ b/src/view/com/util/images/AutoSizedImage.tsx
@@ -6,8 +6,7 @@ import {AppBskyEmbedImages} from '@atproto/api'
 import {msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 
-import {useImageDimensions} from '#/lib/media/image-sizes'
-import {Dimensions} from '#/lib/media/types'
+import type {Dimensions} from '#/lib/media/types'
 import {isNative} from '#/platform/detection'
 import {useLargeAltBadgeEnabled} from '#/state/preferences/large-alt-badge'
 import {atoms as a, useBreakpoints, useTheme} from '#/alf'
@@ -15,30 +14,6 @@ import {ArrowsDiagonalOut_Stroke2_Corner0_Rounded as Fullscreen} from '#/compone
 import {MediaInsetBorder} from '#/components/MediaInsetBorder'
 import {Text} from '#/components/Typography'
 
-function useImageAspectRatio({
-  src,
-  knownDimensions,
-}: {
-  src: string
-  knownDimensions: Dimensions | null
-}) {
-  const [raw] = useImageDimensions({src, knownDimensions})
-  let constrained: number | undefined
-  let max: number | undefined
-  let isCropped: boolean | undefined
-  if (raw !== undefined) {
-    const ratio = 1 / 2 // max of 1:2 ratio in feeds
-    constrained = Math.max(raw, ratio)
-    max = Math.max(raw, 0.25) // max of 1:4 in thread
-    isCropped = raw < constrained
-  }
-  return {
-    constrained,
-    max,
-    isCropped,
-  }
-}
-
 export function ConstrainedImage({
   aspectRatio,
   fullBleed,
@@ -93,23 +68,38 @@ export function AutoSizedImage({
   image: AppBskyEmbedImages.ViewImage
   crop?: 'none' | 'square' | 'constrained'
   hideBadge?: boolean
-  onPress?: (containerRef: AnimatedRef<React.Component<{}, {}, any>>) => void
+  onPress?: (
+    containerRef: AnimatedRef<React.Component<{}, {}, any>>,
+    fetchedDims: Dimensions | null,
+  ) => void
   onLongPress?: () => void
   onPressIn?: () => void
 }) {
   const t = useTheme()
   const {_} = useLingui()
   const largeAlt = useLargeAltBadgeEnabled()
-  const {
-    constrained,
-    max,
-    isCropped: rawIsCropped,
-  } = useImageAspectRatio({
-    src: image.thumb,
-    knownDimensions: image.aspectRatio ?? null,
-  })
   const containerRef = useAnimatedRef()
 
+  const [fetchedDims, setFetchedDims] = React.useState<Dimensions | null>(null)
+  const dims = fetchedDims ?? image.aspectRatio
+  let aspectRatio: number | undefined
+  if (dims) {
+    aspectRatio = dims.width / dims.height
+    if (Number.isNaN(aspectRatio)) {
+      aspectRatio = undefined
+    }
+  }
+
+  let constrained: number | undefined
+  let max: number | undefined
+  let rawIsCropped: boolean | undefined
+  if (aspectRatio !== undefined) {
+    const ratio = 1 / 2 // max of 1:2 ratio in feeds
+    constrained = Math.max(aspectRatio, ratio)
+    max = Math.max(aspectRatio, 0.25) // max of 1:4 in thread
+    rawIsCropped = aspectRatio < constrained
+  }
+
   const cropDisabled = crop === 'none'
   const isCropped = rawIsCropped && !cropDisabled
   const hasAlt = !!image.alt
@@ -123,6 +113,9 @@ export function AutoSizedImage({
         accessibilityIgnoresInvertColors
         accessibilityLabel={image.alt}
         accessibilityHint=""
+        onLoad={e => {
+          setFetchedDims({width: e.source.width, height: e.source.height})
+        }}
       />
       <MediaInsetBorder />
 
@@ -194,7 +187,7 @@ export function AutoSizedImage({
   if (cropDisabled) {
     return (
       <Pressable
-        onPress={() => onPress?.(containerRef)}
+        onPress={() => onPress?.(containerRef, fetchedDims)}
         onLongPress={onLongPress}
         onPressIn={onPressIn}
         // alt here is what screen readers actually use
@@ -216,7 +209,7 @@ export function AutoSizedImage({
         fullBleed={crop === 'square'}
         aspectRatio={constrained ?? 1}>
         <Pressable
-          onPress={() => onPress?.(containerRef)}
+          onPress={() => onPress?.(containerRef, fetchedDims)}
           onLongPress={onLongPress}
           onPressIn={onPressIn}
           // alt here is what screen readers actually use