diff options
Diffstat (limited to 'src/view/com/util/images')
-rw-r--r-- | src/view/com/util/images/AutoSizedImage.tsx | 13 | ||||
-rw-r--r-- | src/view/com/util/images/Gallery.tsx | 14 | ||||
-rw-r--r-- | src/view/com/util/images/ImageLayoutGrid.tsx | 37 |
3 files changed, 48 insertions, 16 deletions
diff --git a/src/view/com/util/images/AutoSizedImage.tsx b/src/view/com/util/images/AutoSizedImage.tsx index ce2389ce2..21f6c529e 100644 --- a/src/view/com/util/images/AutoSizedImage.tsx +++ b/src/view/com/util/images/AutoSizedImage.tsx @@ -1,5 +1,6 @@ import React from 'react' import {DimensionValue, Pressable, View} from 'react-native' +import Animated, {AnimatedRef, useAnimatedRef} from 'react-native-reanimated' import {Image} from 'expo-image' import {AppBskyEmbedImages} from '@atproto/api' import {msg} from '@lingui/macro' @@ -92,7 +93,7 @@ export function AutoSizedImage({ image: AppBskyEmbedImages.ViewImage crop?: 'none' | 'square' | 'constrained' hideBadge?: boolean - onPress?: () => void + onPress?: (containerRef: AnimatedRef<React.Component<{}, {}, any>>) => void onLongPress?: () => void onPressIn?: () => void }) { @@ -107,12 +108,14 @@ export function AutoSizedImage({ src: image.thumb, knownDimensions: image.aspectRatio ?? null, }) + const containerRef = useAnimatedRef() + const cropDisabled = crop === 'none' const isCropped = rawIsCropped && !cropDisabled const hasAlt = !!image.alt const contents = ( - <> + <Animated.View ref={containerRef} collapsable={false}> <Image style={[a.w_full, a.h_full]} source={image.thumb} @@ -185,13 +188,13 @@ export function AutoSizedImage({ )} </View> ) : null} - </> + </Animated.View> ) if (cropDisabled) { return ( <Pressable - onPress={onPress} + onPress={() => onPress?.(containerRef)} onLongPress={onLongPress} onPressIn={onPressIn} // alt here is what screen readers actually use @@ -213,7 +216,7 @@ export function AutoSizedImage({ fullBleed={crop === 'square'} aspectRatio={constrained ?? 1}> <Pressable - onPress={onPress} + onPress={() => onPress?.(containerRef)} onLongPress={onLongPress} onPressIn={onPressIn} // alt here is what screen readers actually use diff --git a/src/view/com/util/images/Gallery.tsx b/src/view/com/util/images/Gallery.tsx index d4d7d223d..0c691ec9a 100644 --- a/src/view/com/util/images/Gallery.tsx +++ b/src/view/com/util/images/Gallery.tsx @@ -1,6 +1,6 @@ import React from 'react' import {Pressable, StyleProp, View, ViewStyle} from 'react-native' -import Animated, {AnimatedRef, useAnimatedRef} from 'react-native-reanimated' +import Animated, {AnimatedRef} from 'react-native-reanimated' import {Image, ImageStyle} from 'expo-image' import {AppBskyEmbedImages} from '@atproto/api' import {msg} from '@lingui/macro' @@ -19,13 +19,14 @@ interface Props { index: number onPress?: ( index: number, - containerRef: AnimatedRef<React.Component<{}, {}, any>>, + containerRefs: AnimatedRef<React.Component<{}, {}, any>>[], ) => void onLongPress?: EventFunction onPressIn?: EventFunction imageStyle?: StyleProp<ImageStyle> viewContext?: PostEmbedViewContext insetBorderStyle?: StyleProp<ViewStyle> + containerRefs: AnimatedRef<React.Component<{}, {}, any>>[] } export function GalleryItem({ @@ -37,6 +38,7 @@ export function GalleryItem({ onLongPress, viewContext, insetBorderStyle, + containerRefs, }: Props) { const t = useTheme() const {_} = useLingui() @@ -45,11 +47,13 @@ export function GalleryItem({ const hasAlt = !!image.alt const hideBadges = viewContext === PostEmbedViewContext.FeedEmbedRecordWithMedia - const containerRef = useAnimatedRef() return ( - <Animated.View style={a.flex_1} ref={containerRef}> + <Animated.View + style={a.flex_1} + ref={containerRefs[index]} + collapsable={false}> <Pressable - onPress={onPress ? () => onPress(index, containerRef) : undefined} + onPress={onPress ? () => onPress(index, containerRefs) : undefined} onPressIn={onPressIn ? () => onPressIn(index) : undefined} onLongPress={onLongPress ? () => onLongPress(index) : undefined} style={[ diff --git a/src/view/com/util/images/ImageLayoutGrid.tsx b/src/view/com/util/images/ImageLayoutGrid.tsx index 9d6a49836..b9b966302 100644 --- a/src/view/com/util/images/ImageLayoutGrid.tsx +++ b/src/view/com/util/images/ImageLayoutGrid.tsx @@ -1,6 +1,6 @@ import React from 'react' import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native' -import {AnimatedRef} from 'react-native-reanimated' +import {AnimatedRef, useAnimatedRef} from 'react-native-reanimated' import {AppBskyEmbedImages} from '@atproto/api' import {PostEmbedViewContext} from '#/view/com/util/post-embeds/types' @@ -11,7 +11,7 @@ interface ImageLayoutGridProps { images: AppBskyEmbedImages.ViewImage[] onPress?: ( index: number, - containerRef: AnimatedRef<React.Component<{}, {}, any>>, + containerRefs: AnimatedRef<React.Component<{}, {}, any>>[], ) => void onLongPress?: (index: number) => void onPressIn?: (index: number) => void @@ -41,7 +41,7 @@ interface ImageLayoutGridInnerProps { images: AppBskyEmbedImages.ViewImage[] onPress?: ( index: number, - containerRef: AnimatedRef<React.Component<{}, {}, any>>, + containerRefs: AnimatedRef<React.Component<{}, {}, any>>[], ) => void onLongPress?: (index: number) => void onPressIn?: (index: number) => void @@ -53,8 +53,14 @@ function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) { const gap = props.gap const count = props.images.length + const containerRef1 = useAnimatedRef() + const containerRef2 = useAnimatedRef() + const containerRef3 = useAnimatedRef() + const containerRef4 = useAnimatedRef() + switch (count) { - case 2: + case 2: { + const containerRefs = [containerRef1, containerRef2] return ( <View style={[a.flex_1, a.flex_row, gap]}> <View style={[a.flex_1, {aspectRatio: 1}]}> @@ -62,6 +68,7 @@ function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) { {...props} index={0} insetBorderStyle={noCorners(['topRight', 'bottomRight'])} + containerRefs={containerRefs} /> </View> <View style={[a.flex_1, {aspectRatio: 1}]}> @@ -69,12 +76,15 @@ function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) { {...props} index={1} insetBorderStyle={noCorners(['topLeft', 'bottomLeft'])} + containerRefs={containerRefs} /> </View> </View> ) + } - case 3: + case 3: { + const containerRefs = [containerRef1, containerRef2, containerRef3] return ( <View style={[a.flex_1, a.flex_row, gap]}> <View style={[a.flex_1, {aspectRatio: 1}]}> @@ -82,6 +92,7 @@ function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) { {...props} index={0} insetBorderStyle={noCorners(['topRight', 'bottomRight'])} + containerRefs={containerRefs} /> </View> <View style={[a.flex_1, {aspectRatio: 1}, gap]}> @@ -94,6 +105,7 @@ function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) { 'bottomLeft', 'bottomRight', ])} + containerRefs={containerRefs} /> </View> <View style={[a.flex_1]}> @@ -105,13 +117,21 @@ function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) { 'bottomLeft', 'topRight', ])} + containerRefs={containerRefs} /> </View> </View> </View> ) + } - case 4: + case 4: { + const containerRefs = [ + containerRef1, + containerRef2, + containerRef3, + containerRef4, + ] return ( <> <View style={[a.flex_row, gap]}> @@ -124,6 +144,7 @@ function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) { 'topRight', 'bottomRight', ])} + containerRefs={containerRefs} /> </View> <View style={[a.flex_1, {aspectRatio: 1.5}]}> @@ -135,6 +156,7 @@ function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) { 'bottomLeft', 'bottomRight', ])} + containerRefs={containerRefs} /> </View> </View> @@ -148,6 +170,7 @@ function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) { 'topRight', 'bottomRight', ])} + containerRefs={containerRefs} /> </View> <View style={[a.flex_1, {aspectRatio: 1.5}]}> @@ -159,11 +182,13 @@ function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) { 'bottomLeft', 'topRight', ])} + containerRefs={containerRefs} /> </View> </View> </> ) + } default: return null |