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
This commit is contained in:
Eric Bailey
2024-09-05 13:45:13 -05:00
committed by GitHub
parent 117926357d
commit 2265fedd2a
12 changed files with 397 additions and 207 deletions
+44 -30
View File
@@ -1,13 +1,14 @@
import React, {ComponentProps, FC} from 'react'
import {Pressable, StyleSheet, Text, View} from 'react-native'
import {Pressable, View} from 'react-native'
import {Image} from 'expo-image'
import {AppBskyEmbedImages} from '@atproto/api'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {isWeb} from '#/platform/detection'
import {useLargeAltBadgeEnabled} from '#/state/preferences/large-alt-badge'
import {atoms as a} from '#/alf'
import {PostEmbedViewContext} from '#/view/com/util/post-embeds/types'
import {atoms as a, useTheme} from '#/alf'
import {Text} from '#/components/Typography'
type EventFunction = (index: number) => void
@@ -17,7 +18,8 @@ interface GalleryItemProps {
onPress?: EventFunction
onLongPress?: EventFunction
onPressIn?: EventFunction
imageStyle: ComponentProps<typeof Image>['style']
imageStyle?: ComponentProps<typeof Image>['style']
viewContext?: PostEmbedViewContext
}
export const GalleryItem: FC<GalleryItemProps> = ({
@@ -27,57 +29,69 @@ export const GalleryItem: FC<GalleryItemProps> = ({
onPress,
onPressIn,
onLongPress,
viewContext,
}) => {
const t = useTheme()
const {_} = useLingui()
const largeAltBadge = useLargeAltBadgeEnabled()
const image = images[index]
const hasAlt = !!image.alt
const hideBadges =
viewContext === PostEmbedViewContext.FeedEmbedRecordWithMedia
return (
<View style={a.flex_1}>
<Pressable
onPress={onPress ? () => onPress(index) : undefined}
onPressIn={onPressIn ? () => onPressIn(index) : undefined}
onLongPress={onLongPress ? () => onLongPress(index) : undefined}
style={a.flex_1}
style={[
a.flex_1,
a.rounded_xs,
a.overflow_hidden,
t.atoms.bg_contrast_25,
imageStyle,
]}
accessibilityRole="button"
accessibilityLabel={image.alt || _(msg`Image`)}
accessibilityHint="">
<Image
source={{uri: image.thumb}}
style={[a.flex_1, a.rounded_xs, imageStyle]}
style={[a.flex_1]}
accessible={true}
accessibilityLabel={image.alt}
accessibilityHint=""
accessibilityIgnoresInvertColors
/>
</Pressable>
{image.alt === '' ? null : (
<View style={styles.altContainer}>
{hasAlt && !hideBadges ? (
<View
accessible={false}
style={[
a.absolute,
a.flex_row,
a.align_center,
a.rounded_xs,
t.atoms.bg_contrast_25,
{
gap: 3,
padding: 3,
bottom: a.p_xs.padding,
right: a.p_xs.padding,
opacity: 0.8,
},
largeAltBadge && [
{
gap: 4,
padding: 5,
},
],
]}>
<Text
style={[styles.alt, largeAltBadge && a.text_xs]}
accessible={false}>
style={[a.font_heavy, largeAltBadge ? a.text_xs : {fontSize: 8}]}>
ALT
</Text>
</View>
)}
) : null}
</View>
)
}
const styles = StyleSheet.create({
altContainer: {
backgroundColor: 'rgba(0, 0, 0, 0.75)',
borderRadius: 6,
paddingHorizontal: 6,
paddingVertical: 3,
position: 'absolute',
// Related to margin/gap hack. This keeps the alt label in the same position
// on all platforms
right: isWeb ? 8 : 5,
bottom: isWeb ? 8 : 5,
},
alt: {
color: 'white',
fontSize: 7,
fontWeight: 'bold',
},
})