Handle record-with-media separately, clarify intent using enums

This commit is contained in:
Eric Bailey
2024-09-04 11:04:03 -05:00
parent 8ca7776578
commit b7017c0b7b
8 changed files with 105 additions and 28 deletions
+6 -2
View File
@@ -2,7 +2,7 @@ import React from 'react'
import {View} from 'react-native' import {View} from 'react-native'
import {AppBskyEmbedRecord} from '@atproto/api' import {AppBskyEmbedRecord} from '@atproto/api'
import {PostEmbeds} from '#/view/com/util/post-embeds' import {PostEmbeds, PostEmbedViewContext} from '#/view/com/util/post-embeds'
import {atoms as a, native, useTheme} from '#/alf' import {atoms as a, native, useTheme} from '#/alf'
let MessageItemEmbed = ({ let MessageItemEmbed = ({
@@ -14,7 +14,11 @@ let MessageItemEmbed = ({
return ( return (
<View style={[a.my_xs, t.atoms.bg, native({flexBasis: 0})]}> <View style={[a.my_xs, t.atoms.bg, native({flexBasis: 0})]}>
<PostEmbeds embed={embed} allowNestedQuotes /> <PostEmbeds
embed={embed}
allowNestedQuotes
viewContext={PostEmbedViewContext.Feed}
/>
</View> </View>
) )
} }
+7 -3
View File
@@ -43,7 +43,7 @@ import {ErrorMessage} from '../util/error/ErrorMessage'
import {Link, TextLink} from '../util/Link' import {Link, TextLink} from '../util/Link'
import {formatCount} from '../util/numeric/format' import {formatCount} from '../util/numeric/format'
import {PostCtrls} from '../util/post-ctrls/PostCtrls' import {PostCtrls} from '../util/post-ctrls/PostCtrls'
import {PostEmbeds} from '../util/post-embeds' import {PostEmbeds, PostEmbedViewContext} from '../util/post-embeds'
import {PostMeta} from '../util/PostMeta' import {PostMeta} from '../util/PostMeta'
import {Text} from '../util/text/Text' import {Text} from '../util/text/Text'
import {PreviewableUserAvatar} from '../util/UserAvatar' import {PreviewableUserAvatar} from '../util/UserAvatar'
@@ -366,7 +366,7 @@ let PostThreadItemLoaded = ({
<PostEmbeds <PostEmbeds
embed={post.embed} embed={post.embed}
moderation={moderation} moderation={moderation}
viewContext="thread-highlighted" viewContext={PostEmbedViewContext.ThreadHighlighted}
/> />
</View> </View>
)} )}
@@ -595,7 +595,11 @@ let PostThreadItemLoaded = ({
) : undefined} ) : undefined}
{post.embed && ( {post.embed && (
<View style={[a.pb_xs]}> <View style={[a.pb_xs]}>
<PostEmbeds embed={post.embed} moderation={moderation} /> <PostEmbeds
embed={post.embed}
moderation={moderation}
viewContext={PostEmbedViewContext.Feed}
/>
</View> </View>
)} )}
<PostCtrls <PostCtrls
+6 -2
View File
@@ -32,7 +32,7 @@ import {LabelsOnMyPost} from '../../../components/moderation/LabelsOnMe'
import {PostAlerts} from '../../../components/moderation/PostAlerts' import {PostAlerts} from '../../../components/moderation/PostAlerts'
import {Link, TextLink} from '../util/Link' import {Link, TextLink} from '../util/Link'
import {PostCtrls} from '../util/post-ctrls/PostCtrls' import {PostCtrls} from '../util/post-ctrls/PostCtrls'
import {PostEmbeds} from '../util/post-embeds' import {PostEmbeds, PostEmbedViewContext} from '../util/post-embeds'
import {PostMeta} from '../util/PostMeta' import {PostMeta} from '../util/PostMeta'
import {Text} from '../util/text/Text' import {Text} from '../util/text/Text'
import {PreviewableUserAvatar} from '../util/UserAvatar' import {PreviewableUserAvatar} from '../util/UserAvatar'
@@ -238,7 +238,11 @@ function PostInner({
/> />
) : undefined} ) : undefined}
{post.embed ? ( {post.embed ? (
<PostEmbeds embed={post.embed} moderation={moderation} /> <PostEmbeds
embed={post.embed}
moderation={moderation}
viewContext={PostEmbedViewContext.Feed}
/>
) : null} ) : null}
</ContentHider> </ContentHider>
<PostCtrls <PostCtrls
+2 -1
View File
@@ -34,7 +34,7 @@ import {useComposerControls} from '#/state/shell/composer'
import {useMergedThreadgateHiddenReplies} from '#/state/threadgate-hidden-replies' import {useMergedThreadgateHiddenReplies} from '#/state/threadgate-hidden-replies'
import {FeedNameText} from '#/view/com/util/FeedInfoText' import {FeedNameText} from '#/view/com/util/FeedInfoText'
import {PostCtrls} from '#/view/com/util/post-ctrls/PostCtrls' import {PostCtrls} from '#/view/com/util/post-ctrls/PostCtrls'
import {PostEmbeds} from '#/view/com/util/post-embeds' import {PostEmbeds, PostEmbedViewContext} from '#/view/com/util/post-embeds'
import {PostMeta} from '#/view/com/util/PostMeta' import {PostMeta} from '#/view/com/util/PostMeta'
import {Text} from '#/view/com/util/text/Text' import {Text} from '#/view/com/util/text/Text'
import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar' import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar'
@@ -488,6 +488,7 @@ let PostContent = ({
embed={postEmbed} embed={postEmbed}
moderation={moderation} moderation={moderation}
onOpen={onOpenEmbed} onOpen={onOpenEmbed}
viewContext={PostEmbedViewContext.Feed}
/> />
</View> </View>
) : null} ) : null}
+11 -8
View File
@@ -55,11 +55,13 @@ export function useImageAspectRatio({
} }
} }
export function SquareFramedImage({ export function ConstrainedImage({
aspectRatio, aspectRatio,
fullBleed,
children, children,
}: { }: {
aspectRatio: number aspectRatio: number
fullBleed?: boolean
children: React.ReactNode children: React.ReactNode
}) { }) {
const t = useTheme() const t = useTheme()
@@ -82,7 +84,7 @@ export function SquareFramedImage({
a.rounded_sm, a.rounded_sm,
a.overflow_hidden, a.overflow_hidden,
t.atoms.bg_contrast_25, t.atoms.bg_contrast_25,
{aspectRatio}, {aspectRatio: fullBleed ? 1 : aspectRatio},
]}> ]}>
{children} {children}
</View> </View>
@@ -94,13 +96,13 @@ export function SquareFramedImage({
export function AutoSizedImage({ export function AutoSizedImage({
image, image,
disableCrop, crop = 'constrained',
onPress, onPress,
onLongPress, onLongPress,
onPressIn, onPressIn,
}: { }: {
image: AppBskyEmbedImages.ViewImage image: AppBskyEmbedImages.ViewImage
disableCrop?: boolean crop?: 'none' | 'square' | 'constrained'
onPress?: () => void onPress?: () => void
onLongPress?: () => void onLongPress?: () => void
onPressIn?: () => void onPressIn?: () => void
@@ -116,7 +118,8 @@ export function AutoSizedImage({
src: image.thumb, src: image.thumb,
dimensions: image.aspectRatio, dimensions: image.aspectRatio,
}) })
const isCropped = rawIsCropped && !disableCrop const cropDisabled = crop === 'none'
const isCropped = rawIsCropped && !cropDisabled
const hasAlt = !!image.alt const hasAlt = !!image.alt
const contents = ( const contents = (
@@ -169,7 +172,7 @@ export function AutoSizedImage({
</> </>
) )
if (disableCrop) { if (cropDisabled) {
return ( return (
<Pressable <Pressable
onPress={onPress} onPress={onPress}
@@ -190,7 +193,7 @@ export function AutoSizedImage({
) )
} else { } else {
return ( return (
<SquareFramedImage aspectRatio={constrained}> <ConstrainedImage fullBleed={crop === 'square'} aspectRatio={constrained}>
<Pressable <Pressable
onPress={onPress} onPress={onPress}
onLongPress={onLongPress} onLongPress={onLongPress}
@@ -201,7 +204,7 @@ export function AutoSizedImage({
style={[a.h_full]}> style={[a.h_full]}>
{contents} {contents}
</Pressable> </Pressable>
</SquareFramedImage> </ConstrainedImage>
) )
} }
} }
+43 -9
View File
@@ -41,17 +41,20 @@ import {Link} from '../Link'
import {PostMeta} from '../PostMeta' import {PostMeta} from '../PostMeta'
import {Text} from '../text/Text' import {Text} from '../text/Text'
import {PostEmbeds} from '.' import {PostEmbeds} from '.'
import {PostEmbedViewContext, QuoteEmbedViewContext} from './types'
export function MaybeQuoteEmbed({ export function MaybeQuoteEmbed({
embed, embed,
onOpen, onOpen,
style, style,
allowNestedQuotes, allowNestedQuotes,
viewContext,
}: { }: {
embed: AppBskyEmbedRecord.View embed: AppBskyEmbedRecord.View
onOpen?: () => void onOpen?: () => void
style?: StyleProp<ViewStyle> style?: StyleProp<ViewStyle>
allowNestedQuotes?: boolean allowNestedQuotes?: boolean
viewContext?: QuoteEmbedViewContext
}) { }) {
const pal = usePalette('default') const pal = usePalette('default')
const {currentAccount} = useSession() const {currentAccount} = useSession()
@@ -67,6 +70,7 @@ export function MaybeQuoteEmbed({
onOpen={onOpen} onOpen={onOpen}
style={style} style={style}
allowNestedQuotes={allowNestedQuotes} allowNestedQuotes={allowNestedQuotes}
viewContext={viewContext}
/> />
) )
} else if (AppBskyEmbedRecord.isViewBlocked(embed.record)) { } else if (AppBskyEmbedRecord.isViewBlocked(embed.record)) {
@@ -113,12 +117,14 @@ function QuoteEmbedModerated({
onOpen, onOpen,
style, style,
allowNestedQuotes, allowNestedQuotes,
viewContext,
}: { }: {
viewRecord: AppBskyEmbedRecord.ViewRecord viewRecord: AppBskyEmbedRecord.ViewRecord
postRecord: AppBskyFeedPost.Record postRecord: AppBskyFeedPost.Record
onOpen?: () => void onOpen?: () => void
style?: StyleProp<ViewStyle> style?: StyleProp<ViewStyle>
allowNestedQuotes?: boolean allowNestedQuotes?: boolean
viewContext?: QuoteEmbedViewContext
}) { }) {
const moderationOpts = useModerationOpts() const moderationOpts = useModerationOpts()
const moderation = React.useMemo(() => { const moderation = React.useMemo(() => {
@@ -144,6 +150,7 @@ function QuoteEmbedModerated({
onOpen={onOpen} onOpen={onOpen}
style={style} style={style}
allowNestedQuotes={allowNestedQuotes} allowNestedQuotes={allowNestedQuotes}
viewContext={viewContext}
/> />
) )
} }
@@ -154,12 +161,14 @@ export function QuoteEmbed({
onOpen, onOpen,
style, style,
allowNestedQuotes, allowNestedQuotes,
viewContext,
}: { }: {
quote: ComposerOptsQuote quote: ComposerOptsQuote
moderation?: ModerationDecision moderation?: ModerationDecision
onOpen?: () => void onOpen?: () => void
style?: StyleProp<ViewStyle> style?: StyleProp<ViewStyle>
allowNestedQuotes?: boolean allowNestedQuotes?: boolean
viewContext?: QuoteEmbedViewContext
}) { }) {
const queryClient = useQueryClient() const queryClient = useQueryClient()
const pal = usePalette('default') const pal = usePalette('default')
@@ -226,15 +235,40 @@ export function QuoteEmbed({
{moderation ? ( {moderation ? (
<PostAlerts modui={moderation.ui('contentView')} style={[a.py_xs]} /> <PostAlerts modui={moderation.ui('contentView')} style={[a.py_xs]} />
) : null} ) : null}
{richText ? (
<RichText {viewContext === QuoteEmbedViewContext.FeedEmbedRecordWithMedia ? (
value={richText} <View style={[a.flex_row, a.gap_md]}>
style={a.text_md} {embed && (
numberOfLines={20} <View style={[{width: 100}]}>
disableLinks <PostEmbeds
/> embed={embed}
) : null} moderation={moderation}
{embed && <PostEmbeds embed={embed} moderation={moderation} />} viewContext={PostEmbedViewContext.FeedEmbedRecordWithMedia}
/>
</View>
)}
{richText ? (
<RichText
value={richText}
style={a.text_md}
numberOfLines={20}
disableLinks
/>
) : null}
</View>
) : (
<>
{richText ? (
<RichText
value={richText}
style={a.text_md}
numberOfLines={20}
disableLinks
/>
) : null}
{embed && <PostEmbeds embed={embed} moderation={moderation} />}
</>
)}
</Link> </Link>
</ContentHider> </ContentHider>
) )
+21 -3
View File
@@ -32,8 +32,11 @@ import {AutoSizedImage} from '../images/AutoSizedImage'
import {ImageLayoutGrid} from '../images/ImageLayoutGrid' import {ImageLayoutGrid} from '../images/ImageLayoutGrid'
import {ExternalLinkEmbed} from './ExternalLinkEmbed' import {ExternalLinkEmbed} from './ExternalLinkEmbed'
import {MaybeQuoteEmbed} from './QuoteEmbed' import {MaybeQuoteEmbed} from './QuoteEmbed'
import {PostEmbedViewContext, QuoteEmbedViewContext} from './types'
import {VideoEmbed} from './VideoEmbed' import {VideoEmbed} from './VideoEmbed'
export * from './types'
type Embed = type Embed =
| AppBskyEmbedRecord.View | AppBskyEmbedRecord.View
| AppBskyEmbedImages.View | AppBskyEmbedImages.View
@@ -55,7 +58,7 @@ export function PostEmbeds({
onOpen?: () => void onOpen?: () => void
style?: StyleProp<ViewStyle> style?: StyleProp<ViewStyle>
allowNestedQuotes?: boolean allowNestedQuotes?: boolean
viewContext?: 'thread-highlighted' viewContext?: PostEmbedViewContext
}) { }) {
const {openLightbox} = useLightboxControls() const {openLightbox} = useLightboxControls()
@@ -70,7 +73,15 @@ export function PostEmbeds({
onOpen={onOpen} onOpen={onOpen}
viewContext={viewContext} viewContext={viewContext}
/> />
<MaybeQuoteEmbed embed={embed.record} onOpen={onOpen} /> <MaybeQuoteEmbed
embed={embed.record}
onOpen={onOpen}
viewContext={
viewContext === PostEmbedViewContext.Feed
? QuoteEmbedViewContext.FeedEmbedRecordWithMedia
: undefined
}
/>
</View> </View>
) )
} }
@@ -129,7 +140,14 @@ export function PostEmbeds({
<ContentHider modui={moderation?.ui('contentMedia')}> <ContentHider modui={moderation?.ui('contentMedia')}>
<View style={[styles.container, style]}> <View style={[styles.container, style]}>
<AutoSizedImage <AutoSizedImage
disableCrop={viewContext === 'thread-highlighted'} crop={
viewContext === PostEmbedViewContext.ThreadHighlighted
? 'none'
: viewContext ===
PostEmbedViewContext.FeedEmbedRecordWithMedia
? 'square'
: 'constrained'
}
image={image} image={image}
onPress={() => _openLightbox(0)} onPress={() => _openLightbox(0)}
onPressIn={() => onPressIn(0)} onPressIn={() => onPressIn(0)}
+9
View File
@@ -0,0 +1,9 @@
export enum PostEmbedViewContext {
ThreadHighlighted = 'ThreadHighlighted',
Feed = 'Feed',
FeedEmbedRecordWithMedia = 'FeedEmbedRecordWithMedia',
}
export enum QuoteEmbedViewContext {
FeedEmbedRecordWithMedia = PostEmbedViewContext.FeedEmbedRecordWithMedia,
}