diff options
author | Eric Bailey <git@esb.lol> | 2024-09-05 13:45:13 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-05 13:45:13 -0500 |
commit | 2265fedd2ac4d006e3c55dbb81ee387b93be9830 (patch) | |
tree | 83ce7cb032161fd8dee24b2a7a6e561ee2bcb9f5 /src/view/com/util/images/ImageLayoutGrid.tsx | |
parent | 117926357d3a59db8fb12f9486f657c7b0f1cf69 (diff) | |
download | voidsky-2265fedd2ac4d006e3c55dbb81ee387b93be9830.tar.zst |
Constrain image heights in feeds and threads (#5129)
* Limit height of images within posts * Add some future-proofness * Comments, improve a11y * Adjust ALT, add crop icon * Fix disableCrop in record-with-media posts * Clean up aspect ratios, handle very tall images * Handle record-with-media separately, clarify intent using enums * Adjust spacing * Adjust rwm embed image size on mobile * Only do reduced layout if images embed * Adjust gap in small embed variant * Clean up grid layout * Hide badge on small variant with one image * Remove crop icon from image grid, leave on single image * Fix sizing in Firefox * Fix fullBleed variant
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, - }, -}) |