import React, {useCallback} from 'react' import { StyleSheet, StyleProp, View, ViewStyle, Image as RNImage, Pressable, Text, } from 'react-native' import { AppBskyEmbedImages, AppBskyEmbedExternal, AppBskyEmbedRecord, AppBskyEmbedRecordWithMedia, AppBskyFeedPost, } from '@atproto/api' import {Link} from '../Link' import {ImageLayoutGrid} from '../images/ImageLayoutGrid' import {ImagesLightbox} from 'state/models/ui/shell' import {useStores} from 'state/index' import {usePalette} from 'lib/hooks/usePalette' import {saveImageModal} from 'lib/media/manip' import {YoutubeEmbed} from './YoutubeEmbed' import {ExternalLinkEmbed} from './ExternalLinkEmbed' import {getYoutubeVideoId} from 'lib/strings/url-helpers' import QuoteEmbed from './QuoteEmbed' import {AutoSizedImage} from '../images/AutoSizedImage' type Embed = | AppBskyEmbedRecord.View | AppBskyEmbedImages.View | AppBskyEmbedExternal.View | AppBskyEmbedRecordWithMedia.View | {$type: string; [k: string]: unknown} export function PostEmbeds({ embed, style, }: { embed?: Embed style?: StyleProp }) { const pal = usePalette('default') const store = useStores() const onPressAltText = useCallback( (alt: string) => { store.shell.openModal({ name: 'alt-text-image-read', altText: alt, }) }, [store.shell], ) if ( AppBskyEmbedRecordWithMedia.isView(embed) && AppBskyEmbedRecord.isViewRecord(embed.record.record) && AppBskyFeedPost.isRecord(embed.record.record.value) && AppBskyFeedPost.validateRecord(embed.record.record.value).success ) { return ( ) } if (AppBskyEmbedRecord.isView(embed)) { if ( AppBskyEmbedRecord.isViewRecord(embed.record) && AppBskyFeedPost.isRecord(embed.record.value) && AppBskyFeedPost.validateRecord(embed.record.value).success ) { return ( ) } } if (AppBskyEmbedImages.isView(embed)) { const {images} = embed if (images.length > 0) { const uris = embed.images.map(img => img.fullsize) const openLightbox = (index: number) => { store.shell.openLightbox(new ImagesLightbox(uris, index)) } const onLongPress = (index: number) => { saveImageModal({uri: uris[index]}) } const onPressIn = (index: number) => { const firstImageToShow = uris[index] RNImage.prefetch(firstImageToShow) uris.forEach(uri => { if (firstImageToShow !== uri) { // First image already prefeched above RNImage.prefetch(uri) } }) } if (images.length === 1) { const {alt, thumb} = images[0] return ( openLightbox(0)} onLongPress={() => onLongPress(0)} onPressIn={() => onPressIn(0)} style={styles.singleImage}> {alt === '' ? null : ( { onPressAltText(alt) }}> ALT )} ) } return ( ) // } } } if (AppBskyEmbedExternal.isView(embed)) { const link = embed.external const youtubeVideoId = getYoutubeVideoId(link.uri) if (youtubeVideoId) { return } return ( ) } return } const styles = StyleSheet.create({ stackContainer: { gap: 6, }, imagesContainer: { marginTop: 8, }, singleImage: { borderRadius: 8, maxHeight: 500, }, extOuter: { borderWidth: 1, borderRadius: 8, marginTop: 4, }, alt: { backgroundColor: 'rgba(0, 0, 0, 0.75)', borderRadius: 6, color: 'white', fontSize: 12, fontWeight: 'bold', letterSpacing: 1, paddingHorizontal: 10, paddingVertical: 3, position: 'absolute', left: 10, top: -26, width: 46, }, })