From dda5ca27feb54e7101cb80d9a38a7edd5440d0ec Mon Sep 17 00:00:00 2001 From: Hailey <153161762+haileyok@users.noreply.github.com> Date: Mon, 8 Jan 2024 21:37:12 -0800 Subject: add expandable context to composer when replying to post (#2419) * add expand replyTo text with animation * add images, quote to replyTo * support withmedia * adjust layout * add embed to all needed openComposer calls * adjust gap * organize imports --- src/view/com/composer/ComposerReplyTo.tsx | 254 ++++++++++++++++++++++++++++++ 1 file changed, 254 insertions(+) create mode 100644 src/view/com/composer/ComposerReplyTo.tsx (limited to 'src/view/com/composer/ComposerReplyTo.tsx') diff --git a/src/view/com/composer/ComposerReplyTo.tsx b/src/view/com/composer/ComposerReplyTo.tsx new file mode 100644 index 000000000..678c8581f --- /dev/null +++ b/src/view/com/composer/ComposerReplyTo.tsx @@ -0,0 +1,254 @@ +import React from 'react' +import {LayoutAnimation, Pressable, StyleSheet, View} from 'react-native' +import {Image} from 'expo-image' +import {useLingui} from '@lingui/react' +import {msg} from '@lingui/macro' +import { + AppBskyEmbedImages, + AppBskyEmbedRecord, + AppBskyEmbedRecordWithMedia, + AppBskyFeedPost, +} from '@atproto/api' +import {ComposerOptsPostRef} from 'state/shell/composer' +import {usePalette} from 'lib/hooks/usePalette' +import {sanitizeDisplayName} from 'lib/strings/display-names' +import {sanitizeHandle} from 'lib/strings/handles' +import {UserAvatar} from 'view/com/util/UserAvatar' +import {Text} from 'view/com/util/text/Text' +import QuoteEmbed from 'view/com/util/post-embeds/QuoteEmbed' + +export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) { + const pal = usePalette('default') + 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 && ( + + )} + + {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', + borderTopWidth: 1, + paddingTop: 16, + paddingBottom: 16, + }, + 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, + }, +}) -- cgit 1.4.1