Only do reduced layout if images embed

This commit is contained in:
Eric Bailey
2024-09-04 13:08:39 -05:00
parent eb067d759a
commit 8ea6155bb4
5 changed files with 59 additions and 32 deletions
+3 -1
View File
@@ -97,12 +97,14 @@ export function ConstrainedImage({
export function AutoSizedImage({ export function AutoSizedImage({
image, image,
crop = 'constrained', crop = 'constrained',
hideBadge,
onPress, onPress,
onLongPress, onLongPress,
onPressIn, onPressIn,
}: { }: {
image: AppBskyEmbedImages.ViewImage image: AppBskyEmbedImages.ViewImage
crop?: 'none' | 'square' | 'constrained' crop?: 'none' | 'square' | 'constrained'
hideBadge?: boolean
onPress?: () => void onPress?: () => void
onLongPress?: () => void onLongPress?: () => void
onPressIn?: () => void onPressIn?: () => void
@@ -133,7 +135,7 @@ export function AutoSizedImage({
accessibilityHint="" accessibilityHint=""
/> />
{hasAlt || isCropped ? ( {(hasAlt || isCropped) && !hideBadge ? (
<View <View
accessible={false} accessible={false}
style={[ style={[
+47 -29
View File
@@ -1,13 +1,14 @@
import React, {ComponentProps, FC} from 'react' 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 {Image} from 'expo-image'
import {AppBskyEmbedImages} from '@atproto/api' import {AppBskyEmbedImages} from '@atproto/api'
import {msg} from '@lingui/macro' import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import {isWeb} from '#/platform/detection'
import {useLargeAltBadgeEnabled} from '#/state/preferences/large-alt-badge' import {useLargeAltBadgeEnabled} from '#/state/preferences/large-alt-badge'
import {atoms as a, useTheme} from '#/alf' import {atoms as a, useTheme} from '#/alf'
import {Crop_Stroke2_Corner0_Rounded as Crop} from '#/components/icons/Crop'
import {Text} from '#/components/Typography'
type EventFunction = (index: number) => void type EventFunction = (index: number) => void
@@ -18,6 +19,7 @@ interface GalleryItemProps {
onLongPress?: EventFunction onLongPress?: EventFunction
onPressIn?: EventFunction onPressIn?: EventFunction
imageStyle: ComponentProps<typeof Image>['style'] imageStyle: ComponentProps<typeof Image>['style']
hideBadges?: boolean
} }
export const GalleryItem: FC<GalleryItemProps> = ({ export const GalleryItem: FC<GalleryItemProps> = ({
@@ -27,11 +29,18 @@ export const GalleryItem: FC<GalleryItemProps> = ({
onPress, onPress,
onPressIn, onPressIn,
onLongPress, onLongPress,
hideBadges,
}) => { }) => {
const t = useTheme() const t = useTheme()
const {_} = useLingui() const {_} = useLingui()
const largeAltBadge = useLargeAltBadgeEnabled() const largeAltBadge = useLargeAltBadgeEnabled()
const image = images[index] const image = images[index]
const hasAlt = !!image.alt
const isCropped = React.useMemo(() => {
if (!image.aspectRatio) return true
const aspect = image.aspectRatio.width / image.aspectRatio.height
return aspect !== 1
}, [image.aspectRatio])
return ( return (
<View style={a.flex_1}> <View style={a.flex_1}>
<Pressable <Pressable
@@ -57,34 +66,43 @@ export const GalleryItem: FC<GalleryItemProps> = ({
accessibilityIgnoresInvertColors accessibilityIgnoresInvertColors
/> />
</Pressable> </Pressable>
{image.alt === '' ? null : ( {(hasAlt || isCropped) && !hideBadges ? (
<View style={styles.altContainer}> <View
<Text accessible={false}
style={[styles.alt, largeAltBadge && a.text_xs]} style={[
accessible={false}> a.absolute,
ALT a.flex_row,
</Text> a.align_center,
a.rounded_xs,
t.atoms.bg_contrast_25,
{
gap: 3,
padding: 3,
bottom: a.p_sm.padding,
right: a.p_sm.padding,
opacity: 0.8,
},
largeAltBadge && [
{
gap: 4,
padding: 5,
},
],
]}>
{isCropped && (
<Crop
fill={t.atoms.text_contrast_high.color}
width={largeAltBadge ? 18 : 12}
/>
)}
{hasAlt && (
<Text
style={[a.font_heavy, largeAltBadge ? a.text_xs : {fontSize: 8}]}>
ALT
</Text>
)}
</View> </View>
)} ) : null}
</View> </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',
},
})
+3 -1
View File
@@ -1,8 +1,9 @@
import React from 'react' import React from 'react'
import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native' import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native'
import {AppBskyEmbedImages} from '@atproto/api' import {AppBskyEmbedImages} from '@atproto/api'
import {GalleryItem} from './Gallery'
import {isWeb} from 'platform/detection' import {isWeb} from 'platform/detection'
import {GalleryItem} from './Gallery'
interface ImageLayoutGridProps { interface ImageLayoutGridProps {
images: AppBskyEmbedImages.ViewImage[] images: AppBskyEmbedImages.ViewImage[]
@@ -10,6 +11,7 @@ interface ImageLayoutGridProps {
onLongPress?: (index: number) => void onLongPress?: (index: number) => void
onPressIn?: (index: number) => void onPressIn?: (index: number) => void
style?: StyleProp<ViewStyle> style?: StyleProp<ViewStyle>
hideBadges?: boolean
} }
export function ImageLayoutGrid({style, ...props}: ImageLayoutGridProps) { export function ImageLayoutGrid({style, ...props}: ImageLayoutGridProps) {
+3 -1
View File
@@ -207,6 +207,7 @@ export function QuoteEmbed({
} }
} }
}, [quote.embeds, allowNestedQuotes]) }, [quote.embeds, allowNestedQuotes])
const isImagesEmbed = AppBskyEmbedImages.isView(embed)
const onBeforePress = React.useCallback(() => { const onBeforePress = React.useCallback(() => {
precacheProfile(queryClient, quote.author) precacheProfile(queryClient, quote.author)
@@ -237,7 +238,8 @@ export function QuoteEmbed({
<PostAlerts modui={moderation.ui('contentView')} style={[a.py_xs]} /> <PostAlerts modui={moderation.ui('contentView')} style={[a.py_xs]} />
) : null} ) : null}
{viewContext === QuoteEmbedViewContext.FeedEmbedRecordWithMedia ? ( {viewContext === QuoteEmbedViewContext.FeedEmbedRecordWithMedia &&
isImagesEmbed ? (
<View style={[a.flex_row, a.gap_md]}> <View style={[a.flex_row, a.gap_md]}>
{embed && ( {embed && (
<View style={[{width: gtMobile ? 100 : 80}]}> <View style={[{width: gtMobile ? 100 : 80}]}>
+3
View File
@@ -164,6 +164,9 @@ export function PostEmbeds({
images={embed.images} images={embed.images}
onPress={_openLightbox} onPress={_openLightbox}
onPressIn={onPressIn} onPressIn={onPressIn}
hideBadges={
viewContext === PostEmbedViewContext.FeedEmbedRecordWithMedia
}
/> />
</View> </View>
</ContentHider> </ContentHider>