import {useMemo} from 'react' import {type StyleProp, View, type ViewStyle} from 'react-native' import {Image} from 'expo-image' import {msg} from '@lingui/core/macro' import {useLingui} from '@lingui/react' import {parseAltFromGIFDescription} from '#/lib/gif-alt-text' import {useHaptics} from '#/lib/haptics' import {shareUrl} from '#/lib/sharing' import { exemptExternalEmbedSources, parseEmbedPlayerFromUrl, } from '#/lib/strings/embed-player' import {toNiceDomain} from '#/lib/strings/url-helpers' import {useExternalEmbedsPrefs} from '#/state/preferences' import { applyImageTransforms, useImageCdnHost, } from '#/state/preferences/image-cdn-host' import {useThumbnailFormat} from '#/state/preferences/thumbnail-format' import {atoms as a, useTheme} from '#/alf' import {Divider} from '#/components/Divider' import {Earth_Stroke2_Corner0_Rounded as Globe} from '#/components/icons/Globe' import {Link} from '#/components/Link' import {PostEmbedViewContext} from '#/components/Post/Embed/types' import {Text} from '#/components/Typography' import {IS_NATIVE} from '#/env' import {IS_ANDROID} from '#/env' import {type app} from '#/lexicons' import {ExternalGif} from './ExternalGif' import {ExternalPlayer} from './ExternalPlayer' import {GifEmbed} from './Gif' export const ExternalEmbed = ({ link, onOpen, post, style, hideAlt, preview, viewContext, }: { link: app.bsky.embed.external.ViewExternal onOpen?: () => void post?: app.bsky.feed.defs.PostView style?: StyleProp hideAlt?: boolean preview?: boolean viewContext?: PostEmbedViewContext }) => { const {_} = useLingui() const t = useTheme() const playHaptic = useHaptics() const externalEmbedPrefs = useExternalEmbedsPrefs() const thumbnailFormat = useThumbnailFormat() const imageCdnHost = useImageCdnHost() const niceUrl = toNiceDomain(link.uri) const imageUri = link.thumb ? preview ? link.thumb : applyImageTransforms(link.thumb, { imageCdnHost, format: thumbnailFormat, }) : undefined const embedPlayerParams = useMemo(() => { const params = parseEmbedPlayerFromUrl(link.uri) if (!params) return const canShow = externalEmbedPrefs?.[params.source] !== 'hide' if (canShow || exemptExternalEmbedSources.has(params.source)) { return params } }, [link.uri, externalEmbedPrefs]) const hasMedia = Boolean(imageUri || embedPlayerParams) const isAndroidCarousel = IS_ANDROID && viewContext === PostEmbedViewContext.FeedCarousel const onPress = () => { playHaptic('Light') onOpen?.() } const onShareExternal = IS_NATIVE ? () => { if (link.uri) { playHaptic('Heavy') void shareUrl(link.uri) } } : undefined if ( embedPlayerParams?.source === 'tenor' || embedPlayerParams?.source === 'klipy' ) { const parsedAlt = parseAltFromGIFDescription(link.description) return ( ) } return ( {({hovered, pressed}) => ( {imageUri && !embedPlayerParams ? ( ) : undefined} {embedPlayerParams?.isGif ? ( ) : embedPlayerParams ? ( ) : undefined} {!embedPlayerParams?.isGif && !embedPlayerParams?.dimensions && ( {link.title || link.uri} )} {link.description ? ( {link.description} ) : undefined} {toNiceDomain(link.uri)} )} ) }