diff options
Diffstat (limited to 'src/view/com/util/images/ImageLayoutGrid.tsx')
-rw-r--r-- | src/view/com/util/images/ImageLayoutGrid.tsx | 107 |
1 files changed, 44 insertions, 63 deletions
diff --git a/src/view/com/util/images/ImageLayoutGrid.tsx b/src/view/com/util/images/ImageLayoutGrid.tsx index ba6c04f50..45da7f076 100644 --- a/src/view/com/util/images/ImageLayoutGrid.tsx +++ b/src/view/com/util/images/ImageLayoutGrid.tsx @@ -1,8 +1,10 @@ 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 {PostEmbedViewContext} from '#/view/com/util/post-embeds/types' +import {atoms as a, useBreakpoints} from '#/alf' import {GalleryItem} from './Gallery' -import {isWeb} from 'platform/detection' interface ImageLayoutGridProps { images: AppBskyEmbedImages.ViewImage[] @@ -10,13 +12,25 @@ interface ImageLayoutGridProps { 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={styles.container}> - <ImageLayoutGridInner {...props} /> + <View style={[gap, {aspectRatio}]}> + <ImageLayoutGridInner {...props} gap={gap} /> </View> </View> ) @@ -27,36 +41,39 @@ interface ImageLayoutGridInnerProps { 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={styles.flexRow}> - <View style={styles.smallItem}> - <GalleryItem {...props} index={0} imageStyle={styles.image} /> + <View style={[a.flex_1, a.flex_row, gap]}> + <View style={[a.flex_1, {aspectRatio: 1}]}> + <GalleryItem {...props} index={0} /> </View> - <View style={styles.smallItem}> - <GalleryItem {...props} index={1} imageStyle={styles.image} /> + <View style={[a.flex_1, {aspectRatio: 1}]}> + <GalleryItem {...props} index={1} /> </View> </View> ) case 3: return ( - <View style={styles.flexRow}> - <View style={styles.threeSingle}> - <GalleryItem {...props} index={0} imageStyle={styles.image} /> + <View style={[a.flex_1, a.flex_row, gap]}> + <View style={{flex: 2}}> + <GalleryItem {...props} index={0} /> </View> - <View style={styles.threeDouble}> - <View style={styles.smallItem}> - <GalleryItem {...props} index={1} imageStyle={styles.image} /> + <View style={[a.flex_1, gap]}> + <View style={[a.flex_1, {aspectRatio: 1}]}> + <GalleryItem {...props} index={1} /> </View> - <View style={styles.smallItem}> - <GalleryItem {...props} index={2} imageStyle={styles.image} /> + <View style={[a.flex_1, {aspectRatio: 1}]}> + <GalleryItem {...props} index={2} /> </View> </View> </View> @@ -65,20 +82,20 @@ function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) { case 4: return ( <> - <View style={styles.flexRow}> - <View style={styles.smallItem}> - <GalleryItem {...props} index={0} imageStyle={styles.image} /> + <View style={[a.flex_row, gap]}> + <View style={[a.flex_1, {aspectRatio: 1}]}> + <GalleryItem {...props} index={0} /> </View> - <View style={styles.smallItem}> - <GalleryItem {...props} index={1} imageStyle={styles.image} /> + <View style={[a.flex_1, {aspectRatio: 1}]}> + <GalleryItem {...props} index={1} /> </View> </View> - <View style={styles.flexRow}> - <View style={styles.smallItem}> - <GalleryItem {...props} index={2} imageStyle={styles.image} /> + <View style={[a.flex_row, gap]}> + <View style={[a.flex_1, {aspectRatio: 1}]}> + <GalleryItem {...props} index={2} /> </View> - <View style={styles.smallItem}> - <GalleryItem {...props} index={3} imageStyle={styles.image} /> + <View style={[a.flex_1, {aspectRatio: 1}]}> + <GalleryItem {...props} index={3} /> </View> </View> </> @@ -88,39 +105,3 @@ function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) { 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, - } - : { - gap: IMAGE_GAP, - }, - flexRow: { - flexDirection: 'row', - gap: isWeb ? undefined : IMAGE_GAP, - }, - smallItem: {flex: 1, aspectRatio: 1}, - image: isWeb - ? { - margin: IMAGE_GAP / 2, - } - : {}, - threeSingle: { - flex: 2, - aspectRatio: isWeb ? 1 : undefined, - }, - threeDouble: { - flex: 1, - gap: isWeb ? undefined : IMAGE_GAP, - }, -}) |