GIF previews in notifications (#4447)
* gifs in notifications * remove try/catch * Limit try/catch scope --------- Co-authored-by: Dan Abramov <dan.abramov@gmail.com>
This commit is contained in:
parent
7ddbc392c3
commit
3dc34be929
3 changed files with 143 additions and 59 deletions
|
@ -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}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
|
|
|
@ -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',
|
||||
},
|
||||
})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue