From afcd9beef4be19ddeb62b518c916d2bbc744dadc Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Sat, 1 Mar 2025 14:46:32 -0600 Subject: [PATCH] Split out ImageEmbed --- src/components/Post/Embed/ImageEmbed.tsx | 99 ++++++++++++++++++++++++ src/components/Post/Embed/index.tsx | 98 +---------------------- 2 files changed, 102 insertions(+), 95 deletions(-) create mode 100644 src/components/Post/Embed/ImageEmbed.tsx diff --git a/src/components/Post/Embed/ImageEmbed.tsx b/src/components/Post/Embed/ImageEmbed.tsx new file mode 100644 index 0000000000..679d14e2cd --- /dev/null +++ b/src/components/Post/Embed/ImageEmbed.tsx @@ -0,0 +1,99 @@ +import {InteractionManager, View} from 'react-native' +import {MeasuredDimensions, runOnJS, runOnUI} from 'react-native-reanimated' +import {Image} from 'expo-image' + +import {HandleRef, measureHandle} from '#/lib/hooks/useHandleRef' +import {useLightboxControls} from '#/state/lightbox' +import {Dimensions} from '#/view/com/lightbox/ImageViewing/@types' +import {AutoSizedImage} from '#/view/com/util/images/AutoSizedImage' +import {ImageLayoutGrid} from '#/view/com/util/images/ImageLayoutGrid' +import {PostEmbedViewContext} from '#/view/com/util/post-embeds/types' +import {atoms as a} from '#/alf' +import {EmbedType} from '#/types/bsky/post' +import {CommonProps} from './types' + +export function ImageEmbed({ + embed, + ...rest +}: CommonProps & { + embed: EmbedType<'images'> +}) { + const {openLightbox} = useLightboxControls() + const {images} = embed.view + + if (images.length > 0) { + const items = images.map(img => ({ + uri: img.fullsize, + thumbUri: img.thumb, + alt: img.alt, + dimensions: img.aspectRatio ?? null, + })) + const _openLightbox = ( + index: number, + thumbRects: (MeasuredDimensions | null)[], + fetchedDims: (Dimensions | null)[], + ) => { + openLightbox({ + images: items.map((item, i) => ({ + ...item, + thumbRect: thumbRects[i] ?? null, + thumbDimensions: fetchedDims[i] ?? null, + type: 'image', + })), + index, + }) + } + const onPress = ( + index: number, + refs: HandleRef[], + fetchedDims: (Dimensions | null)[], + ) => { + const handles = refs.map(r => r.current) + runOnUI(() => { + 'worklet' + const rects = handles.map(measureHandle) + runOnJS(_openLightbox)(index, rects, fetchedDims) + })() + } + const onPressIn = (_: number) => { + InteractionManager.runAfterInteractions(() => { + Image.prefetch(items.map(i => i.uri)) + }) + } + + if (images.length === 1) { + const image = images[0] + return ( + + onPress(0, [containerRef], [dims])} + onPressIn={() => onPressIn(0)} + hideBadge={ + rest.viewContext === PostEmbedViewContext.FeedEmbedRecordWithMedia + } + /> + + ) + } + + return ( + + + + ) + } +} diff --git a/src/components/Post/Embed/index.tsx b/src/components/Post/Embed/index.tsx index 98d7de1ffd..d136494fc2 100644 --- a/src/components/Post/Embed/index.tsx +++ b/src/components/Post/Embed/index.tsx @@ -1,7 +1,5 @@ import React from 'react' -import {InteractionManager, StyleSheet, View} from 'react-native' -import {MeasuredDimensions, runOnJS, runOnUI} from 'react-native-reanimated' -import {Image} from 'expo-image' +import {StyleSheet, View} from 'react-native' import { $Typed, AppBskyFeedDefs, @@ -13,17 +11,12 @@ import { import {Trans} from '@lingui/macro' import {useQueryClient} from '@tanstack/react-query' -import {HandleRef, measureHandle} from '#/lib/hooks/useHandleRef' import {usePalette} from '#/lib/hooks/usePalette' import {InfoCircleIcon} from '#/lib/icons' import {makeProfileLink} from '#/lib/routes/links' -import {useLightboxControls} from '#/state/lightbox' import {useModerationOpts} from '#/state/preferences/moderation-opts' import {unstableCacheProfileView} from '#/state/queries/profile' import {useSession} from '#/state/session' -import {Dimensions} from '#/view/com/lightbox/ImageViewing/@types' -import {AutoSizedImage} from '#/view/com/util/images/AutoSizedImage' -import {ImageLayoutGrid} from '#/view/com/util/images/ImageLayoutGrid' import {Link} from '#/view/com/util/Link' import {ExternalLinkEmbed} from '#/view/com/util/post-embeds/ExternalLinkEmbed' import { @@ -42,6 +35,7 @@ import {SubtleWebHover} from '#/components/SubtleWebHover' import * as bsky from '#/types/bsky' import {Embed as TEmbed, EmbedType, parseEmbed} from '#/types/bsky/post' import {FeedEmbed} from './FeedEmbed' +import {ImageEmbed} from './ImageEmbed' import {ListEmbed} from './ListEmbed' import {CommonProps, EmbedProps} from './types' @@ -88,7 +82,7 @@ function MediaEmbed({ case 'images': { return ( - + ) } @@ -180,92 +174,6 @@ function RecordEmbed({ } } -export function ImagesEmbed({ - embed, - ...rest -}: CommonProps & { - embed: EmbedType<'images'> -}) { - const {openLightbox} = useLightboxControls() - const {images} = embed.view - - if (images.length > 0) { - const items = images.map(img => ({ - uri: img.fullsize, - thumbUri: img.thumb, - alt: img.alt, - dimensions: img.aspectRatio ?? null, - })) - const _openLightbox = ( - index: number, - thumbRects: (MeasuredDimensions | null)[], - fetchedDims: (Dimensions | null)[], - ) => { - openLightbox({ - images: items.map((item, i) => ({ - ...item, - thumbRect: thumbRects[i] ?? null, - thumbDimensions: fetchedDims[i] ?? null, - type: 'image', - })), - index, - }) - } - const onPress = ( - index: number, - refs: HandleRef[], - fetchedDims: (Dimensions | null)[], - ) => { - const handles = refs.map(r => r.current) - runOnUI(() => { - 'worklet' - const rects = handles.map(measureHandle) - runOnJS(_openLightbox)(index, rects, fetchedDims) - })() - } - const onPressIn = (_: number) => { - InteractionManager.runAfterInteractions(() => { - Image.prefetch(items.map(i => i.uri)) - }) - } - - if (images.length === 1) { - const image = images[0] - return ( - - onPress(0, [containerRef], [dims])} - onPressIn={() => onPressIn(0)} - hideBadge={ - rest.viewContext === PostEmbedViewContext.FeedEmbedRecordWithMedia - } - /> - - ) - } - - return ( - - - - ) - } -} - export function PostBlockedEmbed() { const t = useTheme() const pal = usePalette('default')