Add gallery embed type support (display + compose) (#10707)
This commit is contained in:
@@ -2,6 +2,7 @@ import {useRef} from 'react'
|
||||
import {InteractionManager, View} from 'react-native'
|
||||
import {type AnimatedRef} from 'react-native-reanimated'
|
||||
import {Image} from 'expo-image'
|
||||
import {AppBskyEmbedGallery, type AppBskyEmbedImages} from '@atproto/api'
|
||||
|
||||
import {atoms as a, tokens} from '#/alf'
|
||||
import {AutoSizedImage} from '#/components/images/AutoSizedImage'
|
||||
@@ -15,16 +16,29 @@ import {useAnalytics} from '#/analytics'
|
||||
import {type EmbedType} from '#/types/bsky/post'
|
||||
import {type CommonProps} from './types'
|
||||
|
||||
const MAX_GRID_IMAGES = 4
|
||||
|
||||
export function ImageEmbed({
|
||||
embed,
|
||||
...rest
|
||||
}: CommonProps & {
|
||||
embed: EmbedType<'images'>
|
||||
embed: EmbedType<'images'> | EmbedType<'gallery'>
|
||||
}) {
|
||||
const ax = useAnalytics()
|
||||
const {openLightbox} = useLightboxControls()
|
||||
const {images} = embed.view
|
||||
const galleryEnabled = ax.features.enabled(ax.features.PostGalleryEmbedEnable)
|
||||
const images: AppBskyEmbedImages.ViewImage[] =
|
||||
embed.type === 'gallery'
|
||||
? embed.view.items.filter(AppBskyEmbedGallery.isViewImage).map(item => ({
|
||||
thumb: item.thumbnail,
|
||||
fullsize: item.fullsize,
|
||||
alt: item.alt,
|
||||
aspectRatio: item.aspectRatio,
|
||||
}))
|
||||
: embed.view.images
|
||||
const useExpandedLayout =
|
||||
embed.type === 'gallery'
|
||||
? images.length > MAX_GRID_IMAGES
|
||||
: ax.features.enabled(ax.features.PostGalleryEmbedEnable)
|
||||
|
||||
// Captured from AutoSizedImage so the peek-commit handler can reuse the same
|
||||
// ref + dims that a tap would — keeps the lightbox's return animation intact.
|
||||
@@ -109,7 +123,7 @@ export function ImageEmbed({
|
||||
)
|
||||
}
|
||||
|
||||
if (galleryEnabled) {
|
||||
if (useExpandedLayout) {
|
||||
return (
|
||||
<View style={[a.mt_sm, rest.style]}>
|
||||
<Gallery
|
||||
@@ -130,6 +144,7 @@ export function ImageEmbed({
|
||||
onPress={onPress}
|
||||
onPressIn={onPressIn}
|
||||
viewContext={rest.viewContext}
|
||||
isWithinQuote={rest.isWithinQuote}
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
|
||||
@@ -54,6 +54,7 @@ export function Embed({embed: rawEmbed, ...rest}: EmbedProps) {
|
||||
|
||||
switch (embed.type) {
|
||||
case 'images':
|
||||
case 'gallery':
|
||||
case 'link':
|
||||
case 'video': {
|
||||
return <MediaEmbed embed={embed} {...rest} />
|
||||
@@ -89,7 +90,8 @@ function MediaEmbed({
|
||||
embed: TEmbed
|
||||
}) {
|
||||
switch (embed.type) {
|
||||
case 'images': {
|
||||
case 'images':
|
||||
case 'gallery': {
|
||||
return (
|
||||
<ContentHider
|
||||
modui={rest.moderation?.ui('contentMedia')}
|
||||
|
||||
Reference in New Issue
Block a user