diff options
Diffstat (limited to 'src/view/com/util')
-rw-r--r-- | src/view/com/util/images/Gallery.tsx | 13 | ||||
-rw-r--r-- | src/view/com/util/images/ImageLayoutGrid.tsx | 11 | ||||
-rw-r--r-- | src/view/com/util/post-embeds/index.tsx | 33 |
3 files changed, 46 insertions, 11 deletions
diff --git a/src/view/com/util/images/Gallery.tsx b/src/view/com/util/images/Gallery.tsx index e277b7e86..d4d7d223d 100644 --- a/src/view/com/util/images/Gallery.tsx +++ b/src/view/com/util/images/Gallery.tsx @@ -1,5 +1,6 @@ import React from 'react' import {Pressable, StyleProp, View, ViewStyle} from 'react-native' +import Animated, {AnimatedRef, useAnimatedRef} from 'react-native-reanimated' import {Image, ImageStyle} from 'expo-image' import {AppBskyEmbedImages} from '@atproto/api' import {msg} from '@lingui/macro' @@ -16,7 +17,10 @@ type EventFunction = (index: number) => void interface Props { images: AppBskyEmbedImages.ViewImage[] index: number - onPress?: EventFunction + onPress?: ( + index: number, + containerRef: AnimatedRef<React.Component<{}, {}, any>>, + ) => void onLongPress?: EventFunction onPressIn?: EventFunction imageStyle?: StyleProp<ImageStyle> @@ -41,10 +45,11 @@ export function GalleryItem({ const hasAlt = !!image.alt const hideBadges = viewContext === PostEmbedViewContext.FeedEmbedRecordWithMedia + const containerRef = useAnimatedRef() return ( - <View style={a.flex_1}> + <Animated.View style={a.flex_1} ref={containerRef}> <Pressable - onPress={onPress ? () => onPress(index) : undefined} + onPress={onPress ? () => onPress(index, containerRef) : undefined} onPressIn={onPressIn ? () => onPressIn(index) : undefined} onLongPress={onLongPress ? () => onLongPress(index) : undefined} style={[ @@ -95,6 +100,6 @@ export function GalleryItem({ </Text> </View> ) : null} - </View> + </Animated.View> ) } diff --git a/src/view/com/util/images/ImageLayoutGrid.tsx b/src/view/com/util/images/ImageLayoutGrid.tsx index 7475a96c3..830040ba6 100644 --- a/src/view/com/util/images/ImageLayoutGrid.tsx +++ b/src/view/com/util/images/ImageLayoutGrid.tsx @@ -1,5 +1,6 @@ import React from 'react' import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native' +import {AnimatedRef} from 'react-native-reanimated' import {AppBskyEmbedImages} from '@atproto/api' import {PostEmbedViewContext} from '#/view/com/util/post-embeds/types' @@ -8,7 +9,10 @@ import {GalleryItem} from './Gallery' interface ImageLayoutGridProps { images: AppBskyEmbedImages.ViewImage[] - onPress?: (index: number) => void + onPress?: ( + index: number, + containerRef: AnimatedRef<React.Component<{}, {}, any>>, + ) => void onLongPress?: (index: number) => void onPressIn?: (index: number) => void style?: StyleProp<ViewStyle> @@ -36,7 +40,10 @@ export function ImageLayoutGrid({style, ...props}: ImageLayoutGridProps) { interface ImageLayoutGridInnerProps { images: AppBskyEmbedImages.ViewImage[] - onPress?: (index: number) => void + onPress?: ( + index: number, + containerRef: AnimatedRef<React.Component<{}, {}, any>>, + ) => void onLongPress?: (index: number) => void onPressIn?: (index: number) => void viewContext?: PostEmbedViewContext diff --git a/src/view/com/util/post-embeds/index.tsx b/src/view/com/util/post-embeds/index.tsx index 575b26694..19769bcd7 100644 --- a/src/view/com/util/post-embeds/index.tsx +++ b/src/view/com/util/post-embeds/index.tsx @@ -6,6 +6,14 @@ import { View, ViewStyle, } from 'react-native' +import Animated, { + AnimatedRef, + measure, + MeasuredDimensions, + runOnJS, + runOnUI, + useAnimatedRef, +} from 'react-native-reanimated' import {Image} from 'expo-image' import { AppBskyEmbedExternal, @@ -61,6 +69,7 @@ export function PostEmbeds({ viewContext?: PostEmbedViewContext }) { const {openLightbox} = useLightboxControls() + const containerRef = useAnimatedRef() // quote post with media // = @@ -138,13 +147,27 @@ export function PostEmbeds({ alt: img.alt, aspectRatio: img.aspectRatio, })) - const _openLightbox = (index: number) => { + const _openLightbox = ( + index: number, + thumbDims: MeasuredDimensions | null, + ) => { openLightbox({ type: 'images', images: items, index, + thumbDims, }) } + const onPress = ( + index: number, + ref: AnimatedRef<React.Component<{}, {}, any>>, + ) => { + runOnUI(() => { + 'worklet' + const dims = measure(ref) + runOnJS(_openLightbox)(index, dims) + })() + } const onPressIn = (_: number) => { InteractionManager.runAfterInteractions(() => { Image.prefetch(items.map(i => i.uri)) @@ -155,7 +178,7 @@ export function PostEmbeds({ const image = images[0] return ( <ContentHider modui={moderation?.ui('contentMedia')}> - <View style={[a.mt_sm, style]}> + <Animated.View ref={containerRef} style={[a.mt_sm, style]}> <AutoSizedImage crop={ viewContext === PostEmbedViewContext.ThreadHighlighted @@ -166,13 +189,13 @@ export function PostEmbeds({ : 'constrained' } image={image} - onPress={() => _openLightbox(0)} + onPress={() => onPress(0, containerRef)} onPressIn={() => onPressIn(0)} hideBadge={ viewContext === PostEmbedViewContext.FeedEmbedRecordWithMedia } /> - </View> + </Animated.View> </ContentHider> ) } @@ -182,7 +205,7 @@ export function PostEmbeds({ <View style={[a.mt_sm, style]}> <ImageLayoutGrid images={embed.images} - onPress={_openLightbox} + onPress={onPress} onPressIn={onPressIn} viewContext={viewContext} /> |