about summary refs log tree commit diff
path: root/src/view/com/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/com/util')
-rw-r--r--src/view/com/util/images/AutoSizedImage.tsx41
-rw-r--r--src/view/com/util/images/ImageHorzList.tsx22
-rw-r--r--src/view/com/util/images/ImageLayoutGrid.tsx122
-rw-r--r--src/view/com/util/post-embeds/index.tsx4
4 files changed, 126 insertions, 63 deletions
diff --git a/src/view/com/util/images/AutoSizedImage.tsx b/src/view/com/util/images/AutoSizedImage.tsx
index 17e3e809b..8c31f5614 100644
--- a/src/view/com/util/images/AutoSizedImage.tsx
+++ b/src/view/com/util/images/AutoSizedImage.tsx
@@ -9,29 +9,33 @@ import {
 import {Image} from 'expo-image'
 import {clamp} from 'lib/numbers'
 import {useStores} from 'state/index'
-import {Dim} from 'lib/media/manip'
+import {Dimensions} from 'lib/media/types'
 
 export const DELAY_PRESS_IN = 500
 const MIN_ASPECT_RATIO = 0.33 // 1/3
 const MAX_ASPECT_RATIO = 5 // 5/1
 
+interface Props {
+  alt?: string
+  uri: string
+  onPress?: () => void
+  onLongPress?: () => void
+  onPressIn?: () => void
+  style?: StyleProp<ViewStyle>
+  children?: React.ReactNode
+}
+
 export function AutoSizedImage({
+  alt,
   uri,
   onPress,
   onLongPress,
   onPressIn,
   style,
   children = null,
-}: {
-  uri: string
-  onPress?: () => void
-  onLongPress?: () => void
-  onPressIn?: () => void
-  style?: StyleProp<ViewStyle>
-  children?: React.ReactNode
-}) {
+}: Props) {
   const store = useStores()
-  const [dim, setDim] = React.useState<Dim | undefined>(
+  const [dim, setDim] = React.useState<Dimensions | undefined>(
     store.imageSizes.get(uri),
   )
   const [aspectRatio, setAspectRatio] = React.useState<number>(
@@ -59,20 +63,31 @@ export function AutoSizedImage({
         onPressIn={onPressIn}
         delayPressIn={DELAY_PRESS_IN}
         style={[styles.container, style]}>
-        <Image style={[styles.image, {aspectRatio}]} source={uri} />
+        <Image
+          style={[styles.image, {aspectRatio}]}
+          source={uri}
+          accessible={true} // Must set for `accessibilityLabel` to work
+          accessibilityLabel={alt}
+        />
         {children}
       </TouchableOpacity>
     )
   }
+
   return (
     <View style={[styles.container, style]}>
-      <Image style={[styles.image, {aspectRatio}]} source={{uri}} />
+      <Image
+        style={[styles.image, {aspectRatio}]}
+        source={{uri}}
+        accessible={true} // Must set for `accessibilityLabel` to work
+        accessibilityLabel={alt}
+      />
       {children}
     </View>
   )
 }
 
-function calc(dim: Dim) {
+function calc(dim: Dimensions) {
   if (dim.width === 0 || dim.height === 0) {
     return 1
   }
diff --git a/src/view/com/util/images/ImageHorzList.tsx b/src/view/com/util/images/ImageHorzList.tsx
index 40f1948d6..5c232e0b4 100644
--- a/src/view/com/util/images/ImageHorzList.tsx
+++ b/src/view/com/util/images/ImageHorzList.tsx
@@ -7,21 +7,25 @@ import {
   ViewStyle,
 } from 'react-native'
 import {Image} from 'expo-image'
+import {AppBskyEmbedImages} from '@atproto/api'
 
-export function ImageHorzList({
-  uris,
-  onPress,
-  style,
-}: {
-  uris: string[]
+interface Props {
+  images: AppBskyEmbedImages.ViewImage[]
   onPress?: (index: number) => void
   style?: StyleProp<ViewStyle>
-}) {
+}
+
+export function ImageHorzList({images, onPress, style}: Props) {
   return (
     <View style={[styles.flexRow, style]}>
-      {uris.map((uri, i) => (
+      {images.map(({thumb, alt}, i) => (
         <TouchableWithoutFeedback key={i} onPress={() => onPress?.(i)}>
-          <Image source={{uri}} style={styles.image} />
+          <Image
+            source={{uri: thumb}}
+            style={styles.image}
+            accessible={true}
+            accessibilityLabel={alt}
+          />
         </TouchableWithoutFeedback>
       ))}
     </View>
diff --git a/src/view/com/util/images/ImageLayoutGrid.tsx b/src/view/com/util/images/ImageLayoutGrid.tsx
index f4fe59522..51bb04fe9 100644
--- a/src/view/com/util/images/ImageLayoutGrid.tsx
+++ b/src/view/com/util/images/ImageLayoutGrid.tsx
@@ -9,26 +9,25 @@ import {
 } from 'react-native'
 import {Image, ImageStyle} from 'expo-image'
 import {Dimensions} from 'lib/media/types'
+import {AppBskyEmbedImages} from '@atproto/api'
 
 export const DELAY_PRESS_IN = 500
 
-export type ImageLayoutGridType = number
+interface ImageLayoutGridProps {
+  images: AppBskyEmbedImages.ViewImage[]
+  onPress?: (index: number) => void
+  onLongPress?: (index: number) => void
+  onPressIn?: (index: number) => void
+  style?: StyleProp<ViewStyle>
+}
 
 export function ImageLayoutGrid({
-  type,
-  uris,
+  images,
   onPress,
   onLongPress,
   onPressIn,
   style,
-}: {
-  type: ImageLayoutGridType
-  uris: string[]
-  onPress?: (index: number) => void
-  onLongPress?: (index: number) => void
-  onPressIn?: (index: number) => void
-  style?: StyleProp<ViewStyle>
-}) {
+}: ImageLayoutGridProps) {
   const [containerInfo, setContainerInfo] = useState<Dimensions | undefined>()
 
   const onLayout = (evt: LayoutChangeEvent) => {
@@ -42,8 +41,7 @@ export function ImageLayoutGrid({
     <View style={style} onLayout={onLayout}>
       {containerInfo ? (
         <ImageLayoutGridInner
-          type={type}
-          uris={uris}
+          images={images}
           onPress={onPress}
           onPressIn={onPressIn}
           onLongPress={onLongPress}
@@ -54,41 +52,42 @@ export function ImageLayoutGrid({
   )
 }
 
+interface ImageLayoutGridInnerProps {
+  images: AppBskyEmbedImages.ViewImage[]
+  onPress?: (index: number) => void
+  onLongPress?: (index: number) => void
+  onPressIn?: (index: number) => void
+  containerInfo: Dimensions
+}
+
 function ImageLayoutGridInner({
-  type,
-  uris,
+  images,
   onPress,
   onLongPress,
   onPressIn,
   containerInfo,
-}: {
-  type: ImageLayoutGridType
-  uris: string[]
-  onPress?: (index: number) => void
-  onLongPress?: (index: number) => void
-  onPressIn?: (index: number) => void
-  containerInfo: Dimensions
-}) {
+}: ImageLayoutGridInnerProps) {
+  const count = images.length
   const size1 = useMemo<ImageStyle>(() => {
-    if (type === 3) {
+    if (count === 3) {
       const size = (containerInfo.width - 10) / 3
       return {width: size, height: size, resizeMode: 'cover', borderRadius: 4}
     } else {
       const size = (containerInfo.width - 5) / 2
       return {width: size, height: size, resizeMode: 'cover', borderRadius: 4}
     }
-  }, [type, containerInfo])
+  }, [count, containerInfo])
   const size2 = React.useMemo<ImageStyle>(() => {
-    if (type === 3) {
+    if (count === 3) {
       const size = ((containerInfo.width - 10) / 3) * 2 + 5
       return {width: size, height: size, resizeMode: 'cover', borderRadius: 4}
     } else {
       const size = (containerInfo.width - 5) / 2
       return {width: size, height: size, resizeMode: 'cover', borderRadius: 4}
     }
-  }, [type, containerInfo])
+  }, [count, containerInfo])
 
-  if (type === 2) {
+  if (count === 2) {
     return (
       <View style={styles.flexRow}>
         <TouchableOpacity
@@ -96,7 +95,12 @@ function ImageLayoutGridInner({
           onPress={() => onPress?.(0)}
           onPressIn={() => onPressIn?.(0)}
           onLongPress={() => onLongPress?.(0)}>
-          <Image source={{uri: uris[0]}} style={size1} />
+          <Image
+            source={{uri: images[0].thumb}}
+            style={size1}
+            accessible={true}
+            accessibilityLabel={images[0].alt}
+          />
         </TouchableOpacity>
         <View style={styles.wSpace} />
         <TouchableOpacity
@@ -104,12 +108,17 @@ function ImageLayoutGridInner({
           onPress={() => onPress?.(1)}
           onPressIn={() => onPressIn?.(1)}
           onLongPress={() => onLongPress?.(1)}>
-          <Image source={{uri: uris[1]}} style={size1} />
+          <Image
+            source={{uri: images[1].thumb}}
+            style={size1}
+            accessible={true}
+            accessibilityLabel={images[1].alt}
+          />
         </TouchableOpacity>
       </View>
     )
   }
-  if (type === 3) {
+  if (count === 3) {
     return (
       <View style={styles.flexRow}>
         <TouchableOpacity
@@ -117,7 +126,12 @@ function ImageLayoutGridInner({
           onPress={() => onPress?.(0)}
           onPressIn={() => onPressIn?.(0)}
           onLongPress={() => onLongPress?.(0)}>
-          <Image source={{uri: uris[0]}} style={size2} />
+          <Image
+            source={{uri: images[0].thumb}}
+            style={size2}
+            accessible={true}
+            accessibilityLabel={images[0].alt}
+          />
         </TouchableOpacity>
         <View style={styles.wSpace} />
         <View>
@@ -126,7 +140,12 @@ function ImageLayoutGridInner({
             onPress={() => onPress?.(1)}
             onPressIn={() => onPressIn?.(1)}
             onLongPress={() => onLongPress?.(1)}>
-            <Image source={{uri: uris[1]}} style={size1} />
+            <Image
+              source={{uri: images[1].thumb}}
+              style={size1}
+              accessible={true}
+              accessibilityLabel={images[1].alt}
+            />
           </TouchableOpacity>
           <View style={styles.hSpace} />
           <TouchableOpacity
@@ -134,13 +153,18 @@ function ImageLayoutGridInner({
             onPress={() => onPress?.(2)}
             onPressIn={() => onPressIn?.(2)}
             onLongPress={() => onLongPress?.(2)}>
-            <Image source={{uri: uris[2]}} style={size1} />
+            <Image
+              source={{uri: images[2].thumb}}
+              style={size1}
+              accessible={true}
+              accessibilityLabel={images[2].alt}
+            />
           </TouchableOpacity>
         </View>
       </View>
     )
   }
-  if (type === 4) {
+  if (count === 4) {
     return (
       <View style={styles.flexRow}>
         <View>
@@ -149,7 +173,12 @@ function ImageLayoutGridInner({
             onPress={() => onPress?.(0)}
             onPressIn={() => onPressIn?.(0)}
             onLongPress={() => onLongPress?.(0)}>
-            <Image source={{uri: uris[0]}} style={size1} />
+            <Image
+              source={{uri: images[0].thumb}}
+              style={size1}
+              accessible={true}
+              accessibilityLabel={images[0].alt}
+            />
           </TouchableOpacity>
           <View style={styles.hSpace} />
           <TouchableOpacity
@@ -157,7 +186,12 @@ function ImageLayoutGridInner({
             onPress={() => onPress?.(2)}
             onPressIn={() => onPressIn?.(2)}
             onLongPress={() => onLongPress?.(2)}>
-            <Image source={{uri: uris[2]}} style={size1} />
+            <Image
+              source={{uri: images[2].thumb}}
+              style={size1}
+              accessible={true}
+              accessibilityLabel={images[2].alt}
+            />
           </TouchableOpacity>
         </View>
         <View style={styles.wSpace} />
@@ -167,7 +201,12 @@ function ImageLayoutGridInner({
             onPress={() => onPress?.(1)}
             onPressIn={() => onPressIn?.(1)}
             onLongPress={() => onLongPress?.(1)}>
-            <Image source={{uri: uris[1]}} style={size1} />
+            <Image
+              source={{uri: images[1].thumb}}
+              style={size1}
+              accessible={true}
+              accessibilityLabel={images[1].alt}
+            />
           </TouchableOpacity>
           <View style={styles.hSpace} />
           <TouchableOpacity
@@ -175,7 +214,12 @@ function ImageLayoutGridInner({
             onPress={() => onPress?.(3)}
             onPressIn={() => onPressIn?.(3)}
             onLongPress={() => onLongPress?.(3)}>
-            <Image source={{uri: uris[3]}} style={size1} />
+            <Image
+              source={{uri: images[3].thumb}}
+              style={size1}
+              accessible={true}
+              accessibilityLabel={images[3].alt}
+            />
           </TouchableOpacity>
         </View>
       </View>
diff --git a/src/view/com/util/post-embeds/index.tsx b/src/view/com/util/post-embeds/index.tsx
index c15986b76..f37fba342 100644
--- a/src/view/com/util/post-embeds/index.tsx
+++ b/src/view/com/util/post-embeds/index.tsx
@@ -112,6 +112,7 @@ export function PostEmbeds({
           return (
             <View style={[styles.imagesContainer, style]}>
               <AutoSizedImage
+                alt={embed.images[0].alt}
                 uri={embed.images[0].thumb}
                 onPress={() => openLightbox(0)}
                 onLongPress={() => onLongPress(0)}
@@ -124,8 +125,7 @@ export function PostEmbeds({
           return (
             <View style={[styles.imagesContainer, style]}>
               <ImageLayoutGrid
-                type={embed.images.length}
-                uris={embed.images.map(img => img.thumb)}
+                images={embed.images}
                 onPress={openLightbox}
                 onLongPress={onLongPress}
                 onPressIn={onPressIn}