diff --git a/native/chat/settings/thread-settings-media-gallery.react.js b/native/chat/settings/thread-settings-media-gallery.react.js --- a/native/chat/settings/thread-settings-media-gallery.react.js +++ b/native/chat/settings/thread-settings-media-gallery.react.js @@ -1,5 +1,6 @@ // @flow +import { useNavigation, useRoute } from '@react-navigation/native'; import * as React from 'react'; import { View, TouchableOpacity, useWindowDimensions } from 'react-native'; import FastImage from 'react-native-fast-image'; @@ -7,9 +8,18 @@ import Video from 'react-native-video'; import { fetchThreadMedia } from 'lib/actions/thread-actions.js'; +import type { Corners, MediaInfo } from 'lib/types/media-types.js'; import { useServerCall } from 'lib/utils/action-utils.js'; +import { + ImageModalRouteName, + VideoPlaybackModalRouteName, +} from '../../navigation/route-names.js'; import { useStyles } from '../../themes/colors.js'; +import type { + LayoutCoordinates, + VerticalBounds, +} from '../../types/layout-types.js'; const galleryItemGap = 8; const numColumns = 3; @@ -17,6 +27,7 @@ type ThreadSettingsMediaGalleryProps = { +threadID: string, +limit: number, + +verticalBounds: ?VerticalBounds, }; function ThreadSettingsMediaGallery( @@ -24,6 +35,8 @@ ): React.Node { const styles = useStyles(unboundStyles); const { width } = useWindowDimensions(); + const navigation = useNavigation(); + const route = useRoute(); // Explanation of galleryItemWidth: // The FlatList has a horizontal padding of 16px on each side, @@ -35,7 +48,7 @@ const galleryItemWidth = (width - 32 - (numColumns - 1) * galleryItemGap) / numColumns; - const { threadID, limit } = props; + const { threadID, limit, verticalBounds } = props; const [mediaInfos, setMediaInfos] = React.useState([]); const callFetchThreadMedia = useServerCall(fetchThreadMedia); @@ -67,6 +80,55 @@ }; }, [galleryItemWidth, styles.media, styles.mediaContainer]); + const navigateToMedia = React.useCallback( + (nativeEvent, item, index) => { + const { pageX, pageY } = nativeEvent; + + const initialCoordinates: LayoutCoordinates = { + x: pageX, + y: pageY, + width: galleryItemWidth, + height: 180, + }; + + const corners: Corners = { + topLeft: index === 0, + topRight: index === numColumns - 1, + bottomLeft: index === mediaInfos.length - numColumns, + bottomRight: index === mediaInfos.length - 1, + }; + + const mediaInfo: MediaInfo = { + ...item, + index, + corners, + }; + + navigation.navigate<'VideoPlaybackModal' | 'ImageModal'>({ + name: + mediaInfo.type === 'video' + ? VideoPlaybackModalRouteName + : ImageModalRouteName, + key: `multimedia|${threadID}|${mediaInfo.index}`, + params: { + presentedFrom: route.key, + mediaInfo, + item, + initialCoordinates, + verticalBounds, + }, + }); + }, + [ + galleryItemWidth, + mediaInfos.length, + navigation, + route.key, + threadID, + verticalBounds, + ], + ); + const renderItem = React.useCallback( ({ item, index }) => { const containerStyle = @@ -77,7 +139,9 @@ if (item.type === 'photo') { return ( - + navigateToMedia(e.nativeEvent, item, index)} + > - + navigateToMedia(e.nativeEvent, item, index)} + >