Clean up grid layout

This commit is contained in:
Eric Bailey
2024-09-04 20:59:28 -05:00
parent 77323aa466
commit a94a57fa01
2 changed files with 32 additions and 59 deletions
+1 -1
View File
@@ -19,7 +19,7 @@ interface GalleryItemProps {
onPress?: EventFunction onPress?: EventFunction
onLongPress?: EventFunction onLongPress?: EventFunction
onPressIn?: EventFunction onPressIn?: EventFunction
imageStyle: ComponentProps<typeof Image>['style'] imageStyle?: ComponentProps<typeof Image>['style']
viewContext?: PostEmbedViewContext viewContext?: PostEmbedViewContext
} }
+31 -58
View File
@@ -1,10 +1,9 @@
import React from 'react' import React from 'react'
import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native' import {StyleProp, View, ViewStyle} from 'react-native'
import {AppBskyEmbedImages} from '@atproto/api' import {AppBskyEmbedImages} from '@atproto/api'
import {isWeb} from 'platform/detection'
import {PostEmbedViewContext} from '#/view/com/util/post-embeds/types' import {PostEmbedViewContext} from '#/view/com/util/post-embeds/types'
import {atoms as a} from '#/alf' import {atoms as a, useBreakpoints} from '#/alf'
import {GalleryItem} from './Gallery' import {GalleryItem} from './Gallery'
interface ImageLayoutGridProps { interface ImageLayoutGridProps {
@@ -17,14 +16,19 @@ interface ImageLayoutGridProps {
} }
export function ImageLayoutGrid({style, ...props}: ImageLayoutGridProps) { export function ImageLayoutGrid({style, ...props}: ImageLayoutGridProps) {
const {gtMobile} = useBreakpoints()
const gap = const gap =
props.viewContext === PostEmbedViewContext.FeedEmbedRecordWithMedia props.viewContext === PostEmbedViewContext.FeedEmbedRecordWithMedia
? a.gap_2xs ? gtMobile
? a.gap_xs
: a.gap_2xs
: gtMobile
? a.gap_sm
: a.gap_xs : a.gap_xs
return ( return (
<View style={style}> <View style={style}>
<View style={[styles.container, gap]}> <View style={[gap]}>
<ImageLayoutGridInner {...props} /> <ImageLayoutGridInner {...props} gap={gap} />
</View> </View>
</View> </View>
) )
@@ -36,24 +40,22 @@ interface ImageLayoutGridInnerProps {
onLongPress?: (index: number) => void onLongPress?: (index: number) => void
onPressIn?: (index: number) => void onPressIn?: (index: number) => void
viewContext?: PostEmbedViewContext viewContext?: PostEmbedViewContext
gap: {gap: number}
} }
function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) { function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) {
const gap = props.gap
const count = props.images.length const count = props.images.length
const gap =
props.viewContext === PostEmbedViewContext.FeedEmbedRecordWithMedia
? a.gap_2xs
: a.gap_xs
switch (count) { switch (count) {
case 2: case 2:
return ( return (
<View style={[a.flex_row, gap]}> <View style={[a.flex_row, gap]}>
<View style={styles.smallItem}> <View style={[a.flex_1, {aspectRatio: 1}]}>
<GalleryItem {...props} index={0} imageStyle={styles.image} /> <GalleryItem {...props} index={0} />
</View> </View>
<View style={styles.smallItem}> <View style={[a.flex_1, {aspectRatio: 1}]}>
<GalleryItem {...props} index={1} imageStyle={styles.image} /> <GalleryItem {...props} index={1} />
</View> </View>
</View> </View>
) )
@@ -61,15 +63,15 @@ function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) {
case 3: case 3:
return ( return (
<View style={[a.flex_row, gap]}> <View style={[a.flex_row, gap]}>
<View style={styles.threeSingle}> <View style={{flex: 2}}>
<GalleryItem {...props} index={0} imageStyle={styles.image} /> <GalleryItem {...props} index={0} />
</View> </View>
<View style={[styles.threeDouble, gap]}> <View style={[a.flex_1, gap]}>
<View style={styles.smallItem}> <View style={[a.flex_1, {aspectRatio: 1}]}>
<GalleryItem {...props} index={1} imageStyle={styles.image} /> <GalleryItem {...props} index={1} />
</View> </View>
<View style={styles.smallItem}> <View style={[a.flex_1, {aspectRatio: 1}]}>
<GalleryItem {...props} index={2} imageStyle={styles.image} /> <GalleryItem {...props} index={2} />
</View> </View>
</View> </View>
</View> </View>
@@ -79,19 +81,19 @@ function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) {
return ( return (
<> <>
<View style={[a.flex_row, gap]}> <View style={[a.flex_row, gap]}>
<View style={styles.smallItem}> <View style={[a.flex_1, {aspectRatio: 1}]}>
<GalleryItem {...props} index={0} imageStyle={styles.image} /> <GalleryItem {...props} index={0} />
</View> </View>
<View style={styles.smallItem}> <View style={[a.flex_1, {aspectRatio: 1}]}>
<GalleryItem {...props} index={1} imageStyle={styles.image} /> <GalleryItem {...props} index={1} />
</View> </View>
</View> </View>
<View style={[a.flex_row, gap]}> <View style={[a.flex_row, gap]}>
<View style={styles.smallItem}> <View style={[a.flex_1, {aspectRatio: 1}]}>
<GalleryItem {...props} index={2} imageStyle={styles.image} /> <GalleryItem {...props} index={2} />
</View> </View>
<View style={styles.smallItem}> <View style={[a.flex_1, {aspectRatio: 1}]}>
<GalleryItem {...props} index={3} imageStyle={styles.image} /> <GalleryItem {...props} index={3} />
</View> </View>
</View> </View>
</> </>
@@ -101,32 +103,3 @@ function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) {
return null return null
} }
} }
// On web we use margin to calculate gap, as aspectRatio does not properly size
// all images on web. On native though we cannot rely on margin, since the
// negative margin interferes with the swipe controls on pagers.
// https://github.com/facebook/yoga/issues/1418
// https://github.com/bluesky-social/social-app/issues/2601
const IMAGE_GAP = 5
const styles = StyleSheet.create({
container: isWeb
? {
marginHorizontal: -IMAGE_GAP / 2,
marginVertical: -IMAGE_GAP / 2,
}
: {},
smallItem: {flex: 1, aspectRatio: 1},
image: isWeb
? {
margin: IMAGE_GAP / 2,
}
: {},
threeSingle: {
flex: 2,
aspectRatio: isWeb ? 1 : undefined,
},
threeDouble: {
flex: 1,
},
})