import {Pressable, type StyleProp, View, type ViewStyle} from 'react-native' import {type AnimatedRef} from 'react-native-reanimated' import {Image, type ImageStyle} from 'expo-image' import {type AppBskyEmbedImages} from '@atproto/api' import {utils} from '@bsky.app/alf' import {msg} from '@lingui/core/macro' import {useLingui} from '@lingui/react' import {Trans} from '@lingui/react/macro' import {type Dimensions} from '#/lib/media/types' import {useLargeAltBadgeEnabled} from '#/state/preferences/large-alt-badge' import {atoms as a, tokens, useTheme} from '#/alf' import {MediaInsetBorder} from '#/components/MediaInsetBorder' import {ImageContextMenu} from '#/components/Post/Embed/ImageContextMenu' import {PostEmbedViewContext} from '#/components/Post/Embed/types' import {Text} from '#/components/Typography' type EventFunction = (index: number) => void interface Props { images: AppBskyEmbedImages.ViewImage[] index: number onPress?: ( index: number, containerRefs: AnimatedRef[], fetchedDims: (Dimensions | null)[], ) => void onLongPress?: EventFunction onPressIn?: EventFunction imageStyle?: StyleProp viewContext?: PostEmbedViewContext insetBorderStyle?: StyleProp containerRefs: AnimatedRef[] thumbDimsRef: React.RefObject<(Dimensions | null)[]> } export function GalleryItem({ images, index, imageStyle, onPress, onPressIn, onLongPress, viewContext, insetBorderStyle, containerRefs, thumbDimsRef, }: Props) { const t = useTheme() const {_} = useLingui() const largeAltBadge = useLargeAltBadgeEnabled() const image = images[index] const hasAlt = !!image.alt const hideBadges = viewContext === PostEmbedViewContext.FeedEmbedRecordWithMedia const aspect = image.aspectRatio && image.aspectRatio.height > 0 ? image.aspectRatio.width / image.aspectRatio.height : undefined // The tap handler and the peek-commit handler do the same thing: open the // lightbox with this cell's ref + dims so the lightbox's return animation // can target the original thumbnail. const openLightboxAtIndex = onPress ? () => onPress(index, containerRefs, thumbDimsRef.current.slice()) : undefined return ( onPressIn(index) : undefined} onLongPress={onLongPress ? () => onLongPress(index) : undefined} android_ripple={{ color: utils.alpha(t.atoms.bg.backgroundColor, 0.2), foreground: true, }} style={[ a.flex_1, a.overflow_hidden, t.atoms.bg_contrast_25, imageStyle, ]} accessibilityRole="button" accessibilityLabel={image.alt || _(msg`Image`)} accessibilityHint=""> { thumbDimsRef.current[index] = { width: e.source.width, height: e.source.height, } }} loading="lazy" /> {hasAlt && !hideBadges ? ( ALT ) : null} ) }