import React from 'react' import {LayoutAnimation, Pressable, StyleSheet, View} from 'react-native' import {Image} from 'expo-image' import { AppBskyEmbedImages, AppBskyEmbedRecord, AppBskyEmbedRecordWithMedia, AppBskyFeedPost, } from '@atproto/api' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' import {isWeb} from '#/platform/detection' import {sanitizeDisplayName} from 'lib/strings/display-names' import {sanitizeHandle} from 'lib/strings/handles' import {ComposerOptsPostRef} from 'state/shell/composer' import {QuoteEmbed} from 'view/com/util/post-embeds/QuoteEmbed' import {Text} from 'view/com/util/text/Text' import {PreviewableUserAvatar} from 'view/com/util/UserAvatar' import {useTheme} from '#/alf' export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) { const t = useTheme() const {_} = useLingui() const {embed} = replyTo const [showFull, setShowFull] = React.useState(false) const onPress = React.useCallback(() => { setShowFull(prev => !prev) LayoutAnimation.configureNext({ duration: 350, update: {type: 'spring', springDamping: 0.7}, }) }, []) const quote = React.useMemo(() => { if ( AppBskyEmbedRecord.isView(embed) && AppBskyEmbedRecord.isViewRecord(embed.record) && AppBskyFeedPost.isRecord(embed.record.value) ) { // Not going to include the images right now return { author: embed.record.author, cid: embed.record.cid, uri: embed.record.uri, indexedAt: embed.record.indexedAt, text: embed.record.value.text, } } else if ( AppBskyEmbedRecordWithMedia.isView(embed) && AppBskyEmbedRecord.isViewRecord(embed.record.record) && AppBskyFeedPost.isRecord(embed.record.record.value) ) { return { author: embed.record.record.author, cid: embed.record.record.cid, uri: embed.record.record.uri, indexedAt: embed.record.record.indexedAt, text: embed.record.record.value.text, } } }, [embed]) const images = React.useMemo(() => { if (AppBskyEmbedImages.isView(embed)) { return embed.images } else if ( AppBskyEmbedRecordWithMedia.isView(embed) && AppBskyEmbedImages.isView(embed.media) ) { return embed.media.images } }, [embed]) return ( {sanitizeDisplayName( replyTo.author.displayName || sanitizeHandle(replyTo.author.handle), )} {replyTo.text} {images && !replyTo.moderation?.ui('contentMedia').blur && ( )} {showFull && quote && } ) } function ComposerReplyToImages({ images, }: { images: AppBskyEmbedImages.ViewImage[] showFull: boolean }) { return ( {(images.length === 1 && ( )) || (images.length === 2 && ( )) || (images.length === 3 && ( )) || (images.length === 4 && ( ))} ) } const styles = StyleSheet.create({ replyToLayout: { flexDirection: 'row', alignItems: 'flex-start', borderBottomWidth: StyleSheet.hairlineWidth, paddingTop: 4, paddingBottom: 16, marginBottom: 12, }, replyToPost: { flex: 1, paddingLeft: 13, paddingRight: 8, }, replyToBody: { flexDirection: 'row', gap: 10, }, replyToText: { flex: 1, flexGrow: 1, }, imagesContainer: { borderRadius: 6, overflow: 'hidden', marginTop: 2, }, imagesInner: { gap: 2, }, imagesRow: { flexDirection: 'row', }, singleImage: { width: 65, height: 65, }, doubleImageTall: { width: 32.5, height: 65, }, doubleImage: { width: 32.5, height: 32.5, }, })