diff --git a/src/components/MediaViewer/MainMediaDisplay.tsx b/src/components/MediaViewer/MainMediaDisplay.tsx index a9c31f8ba..3ad5b8b7e 100644 --- a/src/components/MediaViewer/MainMediaDisplay.tsx +++ b/src/components/MediaViewer/MainMediaDisplay.tsx @@ -4,15 +4,15 @@ import { } from "components/SharedComponents"; import { View } from "components/styledComponents"; import React, { - useCallback, useMemo, useState, + useMemo, useState, } from "react"; -import type { NativeScrollEvent, NativeSyntheticEvent } from "react-native"; -import { FlatList } from "react-native"; import { Gesture, GestureDetector, GestureHandlerRootView, } from "react-native-gesture-handler"; +import type { CarouselRenderItem, ICarouselInstance } from "react-native-reanimated-carousel"; +import Carousel from "react-native-reanimated-carousel"; import Photo from "realmModels/Photo"; import useDeviceOrientation from "sharedHooks/useDeviceOrientation"; import useTranslation from "sharedHooks/useTranslation"; @@ -37,7 +37,7 @@ interface SoundItem { interface Props { autoPlaySound?: boolean; // automatically start playing a sound when it is visible editable?: boolean; - horizontalScroll: React.Ref; + horizontalScroll: React.Ref; onDeletePhoto: ( uri: string ) => void; onClose: ( ) => void; onDeleteSound: ( uri: string ) => void; @@ -63,19 +63,17 @@ const MainMediaDisplay = ( { const { screenWidth } = useDeviceOrientation( ); const [displayHeight, setDisplayHeight] = useState( 0 ); const [zooming, setZooming] = useState( false ); - const atFirstItem = selectedMediaIndex === 0; const items = useMemo( ( ) => ( [ ...photos.map( photo => ( { ...photo, type: "photo" as const } ) ), ...sounds.map( sound => ( { ...sound, type: "sound" as const } ) ), ] ), [photos, sounds] ); - const atLastItem = selectedMediaIndex === items.length - 1; // t changes a lot, but these strings don't, so using them as useCallback // dependencies keeps that method from getting redefined a lot const deletePhotoLabel = t( "Delete-photo" ); const deleteSoundLabel = t( "Delete-sound" ); - const renderPhoto = useCallback( ( photo: PhotoItem ) => { + const renderPhoto = ( photo: PhotoItem ) => { const uri = Photo.displayLocalOrRemoteLargePhoto( photo ); const hasAttribution = photo?.attribution; return ( @@ -112,14 +110,9 @@ const MainMediaDisplay = ( { } ); - }, [ - deletePhotoLabel, - editable, - onDeletePhoto, - selectedMediaIndex, - ] ); + }; - const renderSound = useCallback( ( sound: SoundItem ) => ( + const renderSound = ( sound: SoundItem ) => ( - ), [ - autoPlaySound, - deleteSoundLabel, - displayHeight, - editable, - items, - onDeleteSound, - screenWidth, - selectedMediaIndex, - ] ); + ); - const renderItem = useCallback( ( { item }: { item: PhotoItem | SoundItem } ) => ( + const renderItem: CarouselRenderItem = ( { item } ) => ( item.type === "photo" ? renderPhoto( item ) : renderSound( item ) - ), [ - renderPhoto, - renderSound, - ] ); + ); - // need getItemLayout for setting initial scroll index - const getItemLayout = useCallback( ( data, idx: number ) => ( { - length: screenWidth, - offset: screenWidth * idx, - index: idx, - } ), [screenWidth] ); - - const handleScrollLeft = useCallback( ( index: number ) => { - if ( atFirstItem ) { return; } - setSelectedMediaIndex( index ); - }, [atFirstItem, setSelectedMediaIndex] ); - - const handleScrollRight = useCallback( ( index: number ) => { - if ( atLastItem ) { return; } - setSelectedMediaIndex( index ); - }, [atLastItem, setSelectedMediaIndex] ); - - const handleScrollEndDrag = useCallback( ( e: NativeSyntheticEvent ) => { - const { contentOffset, layoutMeasurement } = e.nativeEvent; - const { x } = contentOffset; - - const currentOffset = screenWidth * selectedMediaIndex; - - // https://gist.github.com/dozsolti/6d01d0f96d9abced3450a2e6149a2bc3?permalink_comment_id=4107663#gistcomment-4107663 - const index = Math.floor( - Math.floor( x ) / Math.floor( layoutMeasurement.width ), - ); - - if ( x > currentOffset ) { - handleScrollRight( index ); - } else if ( x < currentOffset ) { - handleScrollLeft( index ); - } - }, [ - handleScrollLeft, - handleScrollRight, - screenWidth, - selectedMediaIndex, - ] ); + // // need getItemLayout for setting initial scroll index + // const getItemLayout = useCallback( ( data, idx: number ) => ( { + // length: screenWidth, + // offset: screenWidth * idx, + // index: idx, + // } ), [screenWidth] ); const swipeToCloseGesture = Gesture.Simultaneous( Gesture.Pan( ) @@ -227,7 +175,22 @@ const MainMediaDisplay = ( { > - + + {/* + /> */} + diff --git a/src/components/MediaViewer/MediaViewer.tsx b/src/components/MediaViewer/MediaViewer.tsx index 0c1f4a8d3..ad3f13ad6 100644 --- a/src/components/MediaViewer/MediaViewer.tsx +++ b/src/components/MediaViewer/MediaViewer.tsx @@ -7,8 +7,8 @@ import React, { useRef, useState, } from "react"; -import type { FlatList } from "react-native"; import { StatusBar } from "react-native"; +import type { ICarouselInstance } from "react-native-reanimated-carousel"; import { useSafeAreaInsets } from "react-native-safe-area-context"; import Photo from "realmModels/Photo"; import { BREAKPOINTS } from "sharedHelpers/breakpoint"; @@ -78,7 +78,7 @@ const MediaViewer = ( { const { t } = useTranslation( ); const [mediaToDelete, setMediaToDelete] = useState( null ); - const horizontalScroll = useRef( null ); + const horizontalScroll = useRef( null ); const { screenWidth } = useDeviceOrientation( ); const isLargeScreen = screenWidth > BREAKPOINTS.md; @@ -87,7 +87,7 @@ const MediaViewer = ( { // when a user taps an item in the carousel, the UI needs to automatically // scroll to the index of the item they selected setSelectedMediaIndex( index ); - horizontalScroll?.current?.scrollToIndex( { index, animated: true } ); + horizontalScroll?.current?.scrollTo( { index, animated: true } ); }, [setSelectedMediaIndex] ); // If we've removed an item the selectedPhoto index might refer to a item @@ -96,7 +96,7 @@ const MediaViewer = ( { if ( uris.length > 0 && selectedMediaIndex >= uris.length ) { const newIndex = Math.max( 0, selectedMediaIndex - 1 ); setSelectedMediaIndex( newIndex ); - horizontalScroll?.current?.scrollToIndex( { + horizontalScroll?.current?.scrollTo( { index: newIndex, animated: false, } );