Add parseEmbed utils
This commit is contained in:
@@ -1,13 +1,7 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native'
|
import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native'
|
||||||
import {Image} from 'expo-image'
|
import {Image} from 'expo-image'
|
||||||
import {
|
import {AppBskyFeedDefs} from '@atproto/api'
|
||||||
AppBskyEmbedExternal,
|
|
||||||
AppBskyEmbedImages,
|
|
||||||
AppBskyEmbedRecordWithMedia,
|
|
||||||
AppBskyEmbedVideo,
|
|
||||||
AppBskyFeedDefs,
|
|
||||||
} from '@atproto/api'
|
|
||||||
import {Trans} from '@lingui/macro'
|
import {Trans} from '@lingui/macro'
|
||||||
|
|
||||||
import {parseTenorGif} from '#/lib/strings/embed-player'
|
import {parseTenorGif} from '#/lib/strings/embed-player'
|
||||||
@@ -15,6 +9,7 @@ import {atoms as a, useTheme} from '#/alf'
|
|||||||
import {MediaInsetBorder} from '#/components/MediaInsetBorder'
|
import {MediaInsetBorder} from '#/components/MediaInsetBorder'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {PlayButtonIcon} from '#/components/video/PlayButtonIcon'
|
import {PlayButtonIcon} from '#/components/video/PlayButtonIcon'
|
||||||
|
import {parseEmbed} from '#/types/atproto/post'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Streamlined MediaPreview component which just handles images, gifs, and videos
|
* Streamlined MediaPreview component which just handles images, gifs, and videos
|
||||||
@@ -23,15 +18,17 @@ export function Embed({
|
|||||||
embed,
|
embed,
|
||||||
style,
|
style,
|
||||||
}: {
|
}: {
|
||||||
embed?: AppBskyFeedDefs.PostView['embed']
|
embed: AppBskyFeedDefs.PostView['embed']
|
||||||
style?: StyleProp<ViewStyle>
|
style?: StyleProp<ViewStyle>
|
||||||
}) {
|
}) {
|
||||||
let media = AppBskyEmbedRecordWithMedia.isView(embed) ? embed.media : embed
|
const e = parseEmbed(embed)
|
||||||
|
|
||||||
if (AppBskyEmbedImages.isValidView(media)) {
|
if (!e) return null
|
||||||
|
|
||||||
|
if (e.type === 'images') {
|
||||||
return (
|
return (
|
||||||
<Outer style={style}>
|
<Outer style={style}>
|
||||||
{media.images.map(image => (
|
{e.view.images.map(image => (
|
||||||
<ImageItem
|
<ImageItem
|
||||||
key={image.thumb}
|
key={image.thumb}
|
||||||
thumbnail={image.thumb}
|
thumbnail={image.thumb}
|
||||||
@@ -40,10 +37,10 @@ export function Embed({
|
|||||||
))}
|
))}
|
||||||
</Outer>
|
</Outer>
|
||||||
)
|
)
|
||||||
} else if (AppBskyEmbedExternal.isValidView(media) && media.external.thumb) {
|
} else if (e.type === 'link' && e.view.external.thumb) {
|
||||||
let url: URL | undefined
|
let url: URL | undefined
|
||||||
try {
|
try {
|
||||||
url = new URL(media.external.uri)
|
url = new URL(e.view.external.uri)
|
||||||
} catch {}
|
} catch {}
|
||||||
if (url) {
|
if (url) {
|
||||||
const {success} = parseTenorGif(url)
|
const {success} = parseTenorGif(url)
|
||||||
@@ -51,17 +48,17 @@ export function Embed({
|
|||||||
return (
|
return (
|
||||||
<Outer style={style}>
|
<Outer style={style}>
|
||||||
<GifItem
|
<GifItem
|
||||||
thumbnail={media.external.thumb}
|
thumbnail={e.view.external.thumb}
|
||||||
alt={media.external.title}
|
alt={e.view.external.title}
|
||||||
/>
|
/>
|
||||||
</Outer>
|
</Outer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (AppBskyEmbedVideo.isValidView(media)) {
|
} else if (e.type === 'video') {
|
||||||
return (
|
return (
|
||||||
<Outer style={style}>
|
<Outer style={style}>
|
||||||
<VideoItem thumbnail={media.thumbnail} alt={media.alt} />
|
<VideoItem thumbnail={e.view.thumbnail} alt={e.view.alt} />
|
||||||
</Outer>
|
</Outer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,136 @@
|
|||||||
|
import {
|
||||||
|
AppBskyEmbedExternal,
|
||||||
|
AppBskyEmbedImages,
|
||||||
|
AppBskyEmbedRecord,
|
||||||
|
AppBskyEmbedRecordWithMedia,
|
||||||
|
AppBskyEmbedVideo,
|
||||||
|
AppBskyFeedDefs,
|
||||||
|
AppBskyGraphDefs,
|
||||||
|
AppBskyLabelerDefs,
|
||||||
|
} from '@atproto/api'
|
||||||
|
|
||||||
|
export type View =
|
||||||
|
| {
|
||||||
|
type: 'post'
|
||||||
|
view: AppBskyEmbedRecord.ViewRecord
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'post_not_found'
|
||||||
|
view: AppBskyEmbedRecord.ViewNotFound
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'post_blocked'
|
||||||
|
view: AppBskyEmbedRecord.ViewBlocked
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'post_detached'
|
||||||
|
view: AppBskyEmbedRecord.ViewDetached
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'feed'
|
||||||
|
view: AppBskyFeedDefs.GeneratorView
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'list'
|
||||||
|
view: AppBskyGraphDefs.ListView
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'labeler'
|
||||||
|
view: AppBskyLabelerDefs.LabelerView
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'starter_pack'
|
||||||
|
view: AppBskyGraphDefs.StarterPackViewBasic
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'images'
|
||||||
|
view: AppBskyEmbedImages.View
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'link'
|
||||||
|
view: AppBskyEmbedExternal.View
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'video'
|
||||||
|
view: AppBskyEmbedVideo.View
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'post_with_media'
|
||||||
|
view: View | undefined
|
||||||
|
media: View | undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parseEmbedView(
|
||||||
|
view: AppBskyEmbedRecord.View,
|
||||||
|
): View | undefined {
|
||||||
|
if (AppBskyEmbedRecord.isViewRecord(view.record)) {
|
||||||
|
return {
|
||||||
|
type: 'post',
|
||||||
|
view: view.record,
|
||||||
|
}
|
||||||
|
} else if (AppBskyEmbedRecord.isViewNotFound(view.record)) {
|
||||||
|
return {
|
||||||
|
type: 'post_not_found',
|
||||||
|
view: view.record,
|
||||||
|
}
|
||||||
|
} else if (AppBskyEmbedRecord.isViewBlocked(view.record)) {
|
||||||
|
return {
|
||||||
|
type: 'post_blocked',
|
||||||
|
view: view.record,
|
||||||
|
}
|
||||||
|
} else if (AppBskyEmbedRecord.isViewDetached(view.record)) {
|
||||||
|
return {
|
||||||
|
type: 'post_detached',
|
||||||
|
view: view.record,
|
||||||
|
}
|
||||||
|
} else if (AppBskyFeedDefs.isGeneratorView(view.record)) {
|
||||||
|
return {
|
||||||
|
type: 'feed',
|
||||||
|
view: view.record,
|
||||||
|
}
|
||||||
|
} else if (AppBskyGraphDefs.isListView(view.record)) {
|
||||||
|
return {
|
||||||
|
type: 'list',
|
||||||
|
view: view.record,
|
||||||
|
}
|
||||||
|
} else if (AppBskyLabelerDefs.isLabelerView(view.record)) {
|
||||||
|
return {
|
||||||
|
type: 'labeler',
|
||||||
|
view: view.record,
|
||||||
|
}
|
||||||
|
} else if (AppBskyGraphDefs.isStarterPackViewBasic(view.record)) {
|
||||||
|
return {
|
||||||
|
type: 'starter_pack',
|
||||||
|
view: view.record,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parseEmbed(
|
||||||
|
embed: AppBskyFeedDefs.PostView['embed'],
|
||||||
|
): View | undefined {
|
||||||
|
if (AppBskyEmbedImages.isView(embed)) {
|
||||||
|
return {
|
||||||
|
type: 'images',
|
||||||
|
view: embed,
|
||||||
|
}
|
||||||
|
} else if (AppBskyEmbedExternal.isView(embed)) {
|
||||||
|
return {
|
||||||
|
type: 'link',
|
||||||
|
view: embed,
|
||||||
|
}
|
||||||
|
} else if (AppBskyEmbedVideo.isView(embed)) {
|
||||||
|
return {
|
||||||
|
type: 'video',
|
||||||
|
view: embed,
|
||||||
|
}
|
||||||
|
} else if (AppBskyEmbedRecord.isView(embed)) {
|
||||||
|
return parseEmbedView(embed)
|
||||||
|
} else if (AppBskyEmbedRecordWithMedia.isView(embed)) {
|
||||||
|
return {
|
||||||
|
type: 'post_with_media',
|
||||||
|
view: parseEmbedView(embed.record),
|
||||||
|
media: parseEmbed(embed.media),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user