Files
bsky-social-app/src/view/com/util/images/ImageLayoutGrid.tsx
T
2024-09-05 10:04:14 -05:00

108 lines
3.0 KiB
TypeScript

import React from 'react'
import {StyleProp, View, ViewStyle} from 'react-native'
import {AppBskyEmbedImages} from '@atproto/api'
import {PostEmbedViewContext} from '#/view/com/util/post-embeds/types'
import {atoms as a, useBreakpoints} from '#/alf'
import {GalleryItem} from './Gallery'
interface ImageLayoutGridProps {
images: AppBskyEmbedImages.ViewImage[]
onPress?: (index: number) => void
onLongPress?: (index: number) => void
onPressIn?: (index: number) => void
style?: StyleProp<ViewStyle>
viewContext?: PostEmbedViewContext
}
export function ImageLayoutGrid({style, ...props}: ImageLayoutGridProps) {
const {gtMobile} = useBreakpoints()
const gap =
props.viewContext === PostEmbedViewContext.FeedEmbedRecordWithMedia
? gtMobile
? a.gap_xs
: a.gap_2xs
: gtMobile
? a.gap_sm
: a.gap_xs
const count = props.images.length
const aspectRatio = count === 2 ? 2 : count === 3 ? 1.5 : 1
return (
<View style={style}>
<View style={[gap, {aspectRatio}]}>
<ImageLayoutGridInner {...props} gap={gap} />
</View>
</View>
)
}
interface ImageLayoutGridInnerProps {
images: AppBskyEmbedImages.ViewImage[]
onPress?: (index: number) => void
onLongPress?: (index: number) => void
onPressIn?: (index: number) => void
viewContext?: PostEmbedViewContext
gap: {gap: number}
}
function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) {
const gap = props.gap
const count = props.images.length
switch (count) {
case 2:
return (
<View style={[a.flex_1, a.flex_row, gap]}>
<View style={[a.flex_1, {aspectRatio: 1}]}>
<GalleryItem {...props} index={0} />
</View>
<View style={[a.flex_1, {aspectRatio: 1}]}>
<GalleryItem {...props} index={1} />
</View>
</View>
)
case 3:
return (
<View style={[a.flex_1, a.flex_row, gap]}>
<View style={{flex: 2}}>
<GalleryItem {...props} index={0} />
</View>
<View style={[a.flex_1, gap]}>
<View style={[a.flex_1, {aspectRatio: 1}]}>
<GalleryItem {...props} index={1} />
</View>
<View style={[a.flex_1, {aspectRatio: 1}]}>
<GalleryItem {...props} index={2} />
</View>
</View>
</View>
)
case 4:
return (
<>
<View style={[a.flex_row, gap]}>
<View style={[a.flex_1, {aspectRatio: 1}]}>
<GalleryItem {...props} index={0} />
</View>
<View style={[a.flex_1, {aspectRatio: 1}]}>
<GalleryItem {...props} index={1} />
</View>
</View>
<View style={[a.flex_row, gap]}>
<View style={[a.flex_1, {aspectRatio: 1}]}>
<GalleryItem {...props} index={2} />
</View>
<View style={[a.flex_1, {aspectRatio: 1}]}>
<GalleryItem {...props} index={3} />
</View>
</View>
</>
)
default:
return null
}
}