about summary refs log tree commit diff
path: root/src/view
diff options
context:
space:
mode:
Diffstat (limited to 'src/view')
-rw-r--r--src/view/com/notifications/FeedItem.tsx47
-rw-r--r--src/view/com/util/images/ImageHorzList.tsx57
2 files changed, 79 insertions, 25 deletions
diff --git a/src/view/com/notifications/FeedItem.tsx b/src/view/com/notifications/FeedItem.tsx
index d6c38ea61..9cd7a2917 100644
--- a/src/view/com/notifications/FeedItem.tsx
+++ b/src/view/com/notifications/FeedItem.tsx
@@ -8,6 +8,7 @@ import {
 } from 'react-native'
 import {
   AppBskyActorDefs,
+  AppBskyEmbedExternal,
   AppBskyEmbedImages,
   AppBskyEmbedRecordWithMedia,
   AppBskyFeedDefs,
@@ -51,6 +52,7 @@ import {TimeElapsed} from '../util/TimeElapsed'
 import {PreviewableUserAvatar, UserAvatar} from '../util/UserAvatar'
 
 import hairlineWidth = StyleSheet.hairlineWidth
+import {parseTenorGif} from '#/lib/strings/embed-player'
 
 const MAX_AUTHORS = 5
 
@@ -465,17 +467,48 @@ function AdditionalPostText({post}: {post?: AppBskyFeedDefs.PostView}) {
   const pal = usePalette('default')
   if (post && AppBskyFeedPost.isRecord(post?.record)) {
     const text = post.record.text
-    const images = AppBskyEmbedImages.isView(post.embed)
-      ? post.embed.images
-      : AppBskyEmbedRecordWithMedia.isView(post.embed) &&
-        AppBskyEmbedImages.isView(post.embed.media)
-      ? post.embed.media.images
-      : undefined
+    let images
+    let isGif = false
+
+    if (AppBskyEmbedImages.isView(post.embed)) {
+      images = post.embed.images
+    } else if (
+      AppBskyEmbedRecordWithMedia.isView(post.embed) &&
+      AppBskyEmbedImages.isView(post.embed.media)
+    ) {
+      images = post.embed.media.images
+    } else if (
+      AppBskyEmbedExternal.isView(post.embed) &&
+      post.embed.external.thumb
+    ) {
+      let url: URL | undefined
+      try {
+        url = new URL(post.embed.external.uri)
+      } catch {}
+      if (url) {
+        const {success} = parseTenorGif(url)
+        if (success) {
+          isGif = true
+          images = [
+            {
+              thumb: post.embed.external.thumb,
+              alt: post.embed.external.title,
+              fullsize: post.embed.external.thumb,
+            },
+          ]
+        }
+      }
+    }
+
     return (
       <>
         {text?.length > 0 && <Text style={pal.textLight}>{text}</Text>}
         {images && images.length > 0 && (
-          <ImageHorzList images={images} style={styles.additionalPostImages} />
+          <ImageHorzList
+            images={images}
+            style={styles.additionalPostImages}
+            gif={isGif}
+          />
         )}
       </>
     )
diff --git a/src/view/com/util/images/ImageHorzList.tsx b/src/view/com/util/images/ImageHorzList.tsx
index 12eef14f7..bade2a444 100644
--- a/src/view/com/util/images/ImageHorzList.tsx
+++ b/src/view/com/util/images/ImageHorzList.tsx
@@ -2,39 +2,60 @@ import React from 'react'
 import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native'
 import {Image} from 'expo-image'
 import {AppBskyEmbedImages} from '@atproto/api'
+import {Trans} from '@lingui/macro'
+
+import {atoms as a} from '#/alf'
+import {Text} from '#/components/Typography'
 
 interface Props {
   images: AppBskyEmbedImages.ViewImage[]
   style?: StyleProp<ViewStyle>
+  gif?: boolean
 }
 
-export function ImageHorzList({images, style}: Props) {
+export function ImageHorzList({images, style, gif}: Props) {
   return (
-    <View style={[styles.flexRow, style]}>
+    <View style={[a.flex_row, a.gap_xs, style]}>
       {images.map(({thumb, alt}) => (
-        <Image
+        <View
           key={thumb}
-          source={{uri: thumb}}
-          style={styles.image}
-          accessible={true}
-          accessibilityIgnoresInvertColors
-          accessibilityHint={alt}
-          accessibilityLabel=""
-        />
+          style={[a.relative, a.flex_1, {aspectRatio: 1, maxWidth: 100}]}>
+          <Image
+            key={thumb}
+            source={{uri: thumb}}
+            style={[a.flex_1, a.rounded_xs]}
+            accessible={true}
+            accessibilityIgnoresInvertColors
+            accessibilityHint={alt}
+            accessibilityLabel=""
+          />
+          {gif && (
+            <View style={styles.altContainer}>
+              <Text style={styles.alt}>
+                <Trans>GIF</Trans>
+              </Text>
+            </View>
+          )}
+        </View>
       ))}
     </View>
   )
 }
 
 const styles = StyleSheet.create({
-  flexRow: {
-    flexDirection: 'row',
-    gap: 5,
+  altContainer: {
+    backgroundColor: 'rgba(0, 0, 0, 0.75)',
+    borderRadius: 6,
+    paddingHorizontal: 6,
+    paddingVertical: 3,
+    position: 'absolute',
+    right: 5,
+    bottom: 5,
+    zIndex: 2,
   },
-  image: {
-    maxWidth: 100,
-    aspectRatio: 1,
-    flex: 1,
-    borderRadius: 4,
+  alt: {
+    color: 'white',
+    fontSize: 7,
+    fontWeight: 'bold',
   },
 })