diff --git a/src/components/Attachments/AttachmentCarousel/CarouselItem.js b/src/components/Attachments/AttachmentCarousel/CarouselItem.js index 878b4eef9539..5552f15320f3 100644 --- a/src/components/Attachments/AttachmentCarousel/CarouselItem.js +++ b/src/components/Attachments/AttachmentCarousel/CarouselItem.js @@ -37,6 +37,15 @@ const propTypes = { transactionID: PropTypes.string, }).isRequired, + /** Whether there is only one element in the attachment carousel */ + isSingleItem: PropTypes.bool.isRequired, + + /** The index of the carousel item */ + index: PropTypes.number.isRequired, + + /** The index of the currently active carousel item */ + activeIndex: PropTypes.number.isRequired, + /** onPress callback */ onPress: PropTypes.func, }; @@ -45,7 +54,7 @@ const defaultProps = { onPress: undefined, }; -function CarouselItem({item, onPress}) { +function CarouselItem({item, index, activeIndex, isSingleItem, onPress}) { const styles = useThemeStyles(); const {translate} = useLocalize(); const {isAttachmentHidden} = useContext(ReportAttachmentsContext); @@ -95,6 +104,10 @@ function CarouselItem({item, onPress}) { source={item.source} file={item.file} isAuthTokenRequired={item.isAuthTokenRequired} + isUsedInCarousel + isSingleCarouselItem={isSingleItem} + carouselItemIndex={index} + carouselActiveItemIndex={activeIndex} onPress={onPress} transactionID={item.transactionID} /> diff --git a/src/components/Attachments/AttachmentCarousel/Pager/AttachmentCarouselPagerContext.ts b/src/components/Attachments/AttachmentCarousel/Pager/AttachmentCarouselPagerContext.ts index fd9b57511cc4..270e0b04909c 100644 --- a/src/components/Attachments/AttachmentCarousel/Pager/AttachmentCarouselPagerContext.ts +++ b/src/components/Attachments/AttachmentCarousel/Pager/AttachmentCarouselPagerContext.ts @@ -3,24 +3,7 @@ import {createContext} from 'react'; import type PagerView from 'react-native-pager-view'; import type {SharedValue} from 'react-native-reanimated'; -/** The pager items array is used within the pager to render and navigate between the images */ -type AttachmentCarouselPagerItems = { - /** The source of the image is used to identify each attachment/page in the pager */ - source: string; - - /** The index of the pager item determines the order of the images in the pager */ - index: number; - - /** The active state of the pager item determines whether the image is currently transformable with pinch, pan and tap gestures */ - isActive: boolean; -}; - type AttachmentCarouselPagerContextValue = { - /** The list of items that are shown in the pager */ - pagerItems: AttachmentCarouselPagerItems[]; - - /** The index of the active page */ - activePage: number; pagerRef: ForwardedRef; isPagerScrolling: SharedValue; isScrollEnabled: SharedValue; diff --git a/src/components/Attachments/AttachmentCarousel/Pager/index.tsx b/src/components/Attachments/AttachmentCarousel/Pager/index.tsx index 8704584c3e18..490afb6614ac 100644 --- a/src/components/Attachments/AttachmentCarousel/Pager/index.tsx +++ b/src/components/Attachments/AttachmentCarousel/Pager/index.tsx @@ -6,7 +6,6 @@ import {createNativeWrapper} from 'react-native-gesture-handler'; import type {PagerViewProps} from 'react-native-pager-view'; import PagerView from 'react-native-pager-view'; import Animated, {useAnimatedProps, useSharedValue} from 'react-native-reanimated'; -import CarouselItem from '@components/Attachments/AttachmentCarousel/CarouselItem'; import useThemeStyles from '@hooks/useThemeStyles'; import AttachmentCarouselPagerContext from './AttachmentCarouselPagerContext'; import usePageScrollHandler from './usePageScrollHandler'; @@ -20,31 +19,21 @@ type AttachmentCarouselPagerHandle = { setPage: (selectedPage: number) => void; }; -type Attachment = { +type PagerItem = { + key: string; + url: string; source: string; }; type AttachmentCarouselPagerProps = { - /** The attachments to be rendered in the pager. */ - items: Attachment[]; - - /** The source (URL) of the currently active attachment. */ - activeSource: string; - - /** The index of the initial page to be rendered. */ - initialPage: number; - - /** A callback to be called when the page is changed. */ + items: PagerItem[]; + renderItem: (props: {item: PagerItem; index: number; isActive: boolean}) => React.ReactNode; + initialIndex: number; onPageSelected: () => void; - - /** - * A callback that can be used to toggle the attachment carousel arrows, when the scale of the image changes. - * @param showArrows If set, it will show/hide the arrows. If not set, it will toggle the arrows. - */ onRequestToggleArrows: (showArrows?: boolean) => void; }; -function AttachmentCarouselPager({items, activeSource, initialPage, onPageSelected, onRequestToggleArrows}: AttachmentCarouselPagerProps, ref: ForwardedRef) { +function AttachmentCarouselPager({items, renderItem, initialIndex, onPageSelected, onRequestToggleArrows}: AttachmentCarouselPagerProps, ref: ForwardedRef) { const styles = useThemeStyles(); const pagerRef = useRef(null); @@ -52,8 +41,8 @@ function AttachmentCarouselPager({items, activeSource, initialPage, onPageSelect const isPagerScrolling = useSharedValue(false); const isScrollEnabled = useSharedValue(true); - const activePage = useSharedValue(initialPage); - const [activePageIndex, setActivePageIndex] = useState(initialPage); + const activePage = useSharedValue(initialIndex); + const [activePageState, setActivePageState] = useState(initialIndex); const pageScrollHandler = usePageScrollHandler((e) => { 'worklet'; @@ -63,12 +52,9 @@ function AttachmentCarouselPager({items, activeSource, initialPage, onPageSelect }, []); useEffect(() => { - setActivePageIndex(initialPage); - activePage.value = initialPage; - }, [activePage, initialPage]); - - /** The `pagerItems` object that passed down to the context. Later used to detect current page, whether it's a single image gallery etc. */ - const pagerItems = useMemo(() => items.map((item, index) => ({source: item.source, index, isActive: index === activePageIndex})), [activePageIndex, items]); + setActivePageState(initialIndex); + activePage.value = initialIndex; + }, [activePage, initialIndex]); /** * This callback is passed to the MultiGestureCanvas/Lightbox through the AttachmentCarouselPagerContext. @@ -108,15 +94,13 @@ function AttachmentCarouselPager({items, activeSource, initialPage, onPageSelect const contextValue = useMemo( () => ({ - pagerItems, - activePage: activePageIndex, + pagerRef, isPagerScrolling, isScrollEnabled, - pagerRef, onTap: handleTap, onScaleChanged: handleScaleChange, }), - [pagerItems, activePageIndex, isPagerScrolling, isScrollEnabled, handleTap, handleScaleChange], + [isPagerScrolling, isScrollEnabled, handleTap, handleScaleChange], ); const animatedProps = useAnimatedProps(() => ({ @@ -137,21 +121,6 @@ function AttachmentCarouselPager({items, activeSource, initialPage, onPageSelect [], ); - const carouselItems = items.map((item, index) => ( - - - - )); - return ( - {carouselItems} + {items.map((item, index) => ( + + {renderItem({item, index, isActive: index === activePageState})} + + ))} ); diff --git a/src/components/Attachments/AttachmentCarousel/index.native.js b/src/components/Attachments/AttachmentCarousel/index.native.js index 228f0d597a32..fa24ccd0ef53 100644 --- a/src/components/Attachments/AttachmentCarousel/index.native.js +++ b/src/components/Attachments/AttachmentCarousel/index.native.js @@ -13,6 +13,7 @@ import variables from '@styles/variables'; import ONYXKEYS from '@src/ONYXKEYS'; import {defaultProps, propTypes} from './attachmentCarouselPropTypes'; import CarouselButtons from './CarouselButtons'; +import CarouselItem from './CarouselItem'; import extractAttachmentsFromReport from './extractAttachmentsFromReport'; import AttachmentCarouselPager from './Pager'; import useCarouselArrows from './useCarouselArrows'; @@ -102,6 +103,24 @@ function AttachmentCarousel({report, reportActions, parentReportActions, source, [setShouldShowArrows], ); + /** + * Defines how a single attachment should be rendered + * @param {{ reportActionID: String, isAuthTokenRequired: Boolean, source: String, file: { name: String }, hasBeenFlagged: Boolean }} item + * @returns {JSX.Element} + */ + const renderItem = useCallback( + ({item, index, isActive}) => ( + + ), + [activeSource, attachments.length, page], + ); + return ( {page == null ? ( @@ -129,8 +148,8 @@ function AttachmentCarousel({report, reportActions, parentReportActions, source, updatePage(newPage)} ref={pagerRef} diff --git a/src/components/Attachments/AttachmentView/AttachmentViewImage/index.js b/src/components/Attachments/AttachmentView/AttachmentViewImage/index.js index 67f87b1733d3..14c60458b044 100755 --- a/src/components/Attachments/AttachmentView/AttachmentViewImage/index.js +++ b/src/components/Attachments/AttachmentView/AttachmentViewImage/index.js @@ -12,7 +12,21 @@ const propTypes = { ...withLocalizePropTypes, }; -function AttachmentViewImage({url, file, isAuthTokenRequired, isFocused, loadComplete, onPress, onError, isImage, translate}) { +function AttachmentViewImage({ + url, + file, + isAuthTokenRequired, + isUsedInCarousel, + isSingleCarouselItem, + carouselItemIndex, + carouselActiveItemIndex, + isFocused, + loadComplete, + onPress, + onError, + isImage, + translate, +}) { const styles = useThemeStyles(); const children = ( ); diff --git a/src/components/Attachments/AttachmentView/index.js b/src/components/Attachments/AttachmentView/index.js index fafdbd27d844..33eab13f3851 100755 --- a/src/components/Attachments/AttachmentView/index.js +++ b/src/components/Attachments/AttachmentView/index.js @@ -79,6 +79,9 @@ function AttachmentView({ translate, isFocused, isUsedInCarousel, + isSingleCarouselItem, + carouselItemIndex, + carouselActiveItemIndex, isUsedInAttachmentModal, isWorkspaceAvatar, maybeIcon, @@ -144,6 +147,8 @@ function AttachmentView({ isFocused={isFocused} isAuthTokenRequired={isAuthTokenRequired} encryptedSourceUrl={encryptedSourceUrl} + carouselItemIndex={carouselItemIndex} + carouselActiveItemIndex={carouselActiveItemIndex} onPress={onPress} onToggleKeyboard={onToggleKeyboard} onLoadComplete={() => !loadComplete && setLoadComplete(true)} @@ -172,6 +177,9 @@ function AttachmentView({ loadComplete={loadComplete} isFocused={isFocused} isUsedInCarousel={isUsedInCarousel} + isSingleCarouselItem={isSingleCarouselItem} + carouselItemIndex={carouselItemIndex} + carouselActiveItemIndex={carouselActiveItemIndex} isImage={isImage} onPress={onPress} onError={() => { diff --git a/src/components/Attachments/AttachmentView/propTypes.js b/src/components/Attachments/AttachmentView/propTypes.js index 0a0d654912d3..d78bed8526b8 100644 --- a/src/components/Attachments/AttachmentView/propTypes.js +++ b/src/components/Attachments/AttachmentView/propTypes.js @@ -14,6 +14,18 @@ const attachmentViewPropTypes = { /** Whether this AttachmentView is shown as part of a AttachmentCarousel */ isUsedInCarousel: PropTypes.bool, + /** When "isUsedInCarousel" is set to true, determines whether there is only one item in the carousel */ + isSingleCarouselItem: PropTypes.bool, + + /** Whether this AttachmentView is shown as part of an AttachmentModal */ + isUsedInAttachmentModal: PropTypes.bool, + + /** The index of the carousel item */ + carouselItemIndex: PropTypes.number, + + /** The index of the currently active carousel item */ + carouselActiveItemIndex: PropTypes.number, + /** Function for handle on press */ onPress: PropTypes.func, @@ -27,8 +39,11 @@ const attachmentViewDefaultProps = { name: '', }, isFocused: false, - isSingleElement: false, isUsedInCarousel: false, + isSingleCarouselItem: false, + carouselItemIndex: 0, + carouselActiveItemIndex: 0, + isSingleElement: false, isUsedInAttachmentModal: false, onPress: undefined, onScaleChanged: () => {}, diff --git a/src/components/ImageView/index.native.tsx b/src/components/ImageView/index.native.tsx index 24f7ffb1dac3..8de1946ef554 100644 --- a/src/components/ImageView/index.native.tsx +++ b/src/components/ImageView/index.native.tsx @@ -3,13 +3,28 @@ import Lightbox from '@components/Lightbox'; import {DEFAULT_ZOOM_RANGE} from '@components/MultiGestureCanvas'; import type {ImageViewProps} from './types'; -function ImageView({isAuthTokenRequired = false, url, style, zoomRange = DEFAULT_ZOOM_RANGE, onError}: ImageViewProps) { +function ImageView({ + isAuthTokenRequired = false, + url, + style, + zoomRange = DEFAULT_ZOOM_RANGE, + onError, + isUsedInCarousel = false, + isSingleCarouselItem = false, + carouselItemIndex = 0, + carouselActiveItemIndex = 0, +}: ImageViewProps) { + const hasSiblingCarouselItems = isUsedInCarousel && !isSingleCarouselItem; + return ( ); diff --git a/src/components/ImageView/types.ts b/src/components/ImageView/types.ts index bb63373324cb..b85115874a5a 100644 --- a/src/components/ImageView/types.ts +++ b/src/components/ImageView/types.ts @@ -14,6 +14,18 @@ type ImageViewProps = { /** Handles errors while displaying the image */ onError?: () => void; + /** Whether this AttachmentView is shown as part of a AttachmentCarousel */ + isUsedInCarousel?: boolean; + + /** When "isUsedInCarousel" is set to true, determines whether there is only one item in the carousel */ + isSingleCarouselItem?: boolean; + + /** The index of the carousel item */ + carouselItemIndex?: number; + + /** The index of the currently active carousel item */ + carouselActiveItemIndex?: number; + /** Additional styles to add to the component */ style?: StyleProp; diff --git a/src/components/Lightbox/index.tsx b/src/components/Lightbox/index.tsx index 36cb175e3c45..aeec1876eb93 100644 --- a/src/components/Lightbox/index.tsx +++ b/src/components/Lightbox/index.tsx @@ -1,8 +1,6 @@ -import React, {useCallback, useContext, useEffect, useMemo, useState} from 'react'; +import React, {useCallback, useEffect, useMemo, useState} from 'react'; import type {LayoutChangeEvent, NativeSyntheticEvent, StyleProp, ViewStyle} from 'react-native'; import {ActivityIndicator, PixelRatio, StyleSheet, View} from 'react-native'; -import {useSharedValue} from 'react-native-reanimated'; -import AttachmentCarouselPagerContext from '@components/Attachments/AttachmentCarousel/Pager/AttachmentCarouselPagerContext'; import Image from '@components/Image'; import MultiGestureCanvas, {DEFAULT_ZOOM_RANGE} from '@components/MultiGestureCanvas'; import type {CanvasSize, ContentSize, OnScaleChangedCallback, ZoomRange} from '@components/MultiGestureCanvas/types'; @@ -33,6 +31,15 @@ type LightboxProps = { /** Additional styles to add to the component */ style?: StyleProp; + /** The index of the carousel item */ + index?: number; + + /** The index of the currently active carousel item */ + activeIndex?: number; + + /** Whether the Lightbox is used within a carousel component and there are other sibling elements */ + hasSiblingCarouselItems?: boolean; + /** Range of zoom that can be applied to the content by pinching or double tapping. */ zoomRange?: Partial; }; @@ -40,53 +47,19 @@ type LightboxProps = { /** * On the native layer, we use a image library to handle zoom functionality */ -function Lightbox({isAuthTokenRequired = false, uri, onScaleChanged: onScaleChangedProp, onError, style, zoomRange = DEFAULT_ZOOM_RANGE}: LightboxProps) { +function Lightbox({ + isAuthTokenRequired = false, + uri, + onScaleChanged, + onError, + style, + index = 0, + activeIndex = 0, + hasSiblingCarouselItems = false, + zoomRange = DEFAULT_ZOOM_RANGE, +}: LightboxProps) { const StyleUtils = useStyleUtils(); - /** - * React hooks must be used in the render function of the component at top-level and unconditionally. - * Therefore, in order to provide a default value for "isPagerScrolling" if the "AttachmentCarouselPagerContext" is not available, - * we need to create a shared value that can be used in the render function. - */ - const isPagerScrollingFallback = useSharedValue(false); - - const attachmentCarouselPagerContext = useContext(AttachmentCarouselPagerContext); - const { - isUsedInCarousel, - isSingleCarouselItem, - isPagerScrolling, - page, - activePage, - onTap, - onScaleChanged: onScaleChangedContext, - pagerRef, - } = useMemo(() => { - if (attachmentCarouselPagerContext === null) { - return { - isUsedInCarousel: false, - isSingleCarouselItem: true, - isPagerScrolling: isPagerScrollingFallback, - page: 0, - activePage: 0, - onTap: () => {}, - onScaleChanged: () => {}, - pagerRef: undefined, - }; - } - - const foundPage = attachmentCarouselPagerContext.pagerItems.findIndex((item) => item.source === uri); - return { - ...attachmentCarouselPagerContext, - isUsedInCarousel: true, - isSingleCarouselItem: attachmentCarouselPagerContext.pagerItems.length === 1, - page: foundPage, - }; - }, [attachmentCarouselPagerContext, isPagerScrollingFallback, uri]); - - /** Whether the Lightbox is used within an attachment carousel and there are more than one page in the carousel */ - const hasSiblingCarouselItems = isUsedInCarousel && !isSingleCarouselItem; - const isActive = page === activePage; - const [canvasSize, setCanvasSize] = useState(); const isCanvasLoading = canvasSize === undefined; const updateCanvasSize = useCallback( @@ -127,9 +100,9 @@ function Lightbox({isAuthTokenRequired = false, uri, onScaleChanged: onScaleChan } const indexCanvasOffset = Math.floor((NUMBER_OF_CONCURRENT_LIGHTBOXES - 1) / 2) || 0; - const indexOutOfRange = page > activePage + indexCanvasOffset || page < activePage - indexCanvasOffset; + const indexOutOfRange = index > activeIndex + indexCanvasOffset || index < activeIndex - indexCanvasOffset; return !indexOutOfRange; - }, [activePage, hasSiblingCarouselItems, page]); + }, [activeIndex, hasSiblingCarouselItems, index]); const [isLightboxImageLoaded, setLightboxImageLoaded] = useState(false); const [isFallbackVisible, setFallbackVisible] = useState(!isLightboxVisible); @@ -153,6 +126,7 @@ function Lightbox({isAuthTokenRequired = false, uri, onScaleChanged: onScaleChan // because it's only going to be rendered after the fallback image is hidden. const shouldShowLightbox = isLightboxImageLoaded && !isFallbackVisible; + const isActive = index === activeIndex; const isFallbackStillLoading = isFallbackVisible && !isFallbackImageLoaded; const isLightboxStillLoading = isLightboxVisible && !isLightboxImageLoaded; const isLoading = isActive && (isCanvasLoading || isFallbackStillLoading || isLightboxStillLoading); @@ -186,14 +160,6 @@ function Lightbox({isAuthTokenRequired = false, uri, onScaleChanged: onScaleChan } }, [hasSiblingCarouselItems, isActive, isFallbackVisible, isLightboxImageLoaded, isLightboxVisible]); - const scaleChange = useCallback( - (scale: number) => { - onScaleChangedProp?.(scale); - onScaleChangedContext?.(scale); - }, - [onScaleChangedContext, onScaleChangedProp], - ); - return ( ; - /** A shared value of type boolean, that indicates disabled the transformation gestures (pinch, pan, double tap) */ - shouldDisableTransformationGestures?: SharedValue; - - /** If there is a pager wrapping the canvas, we need to disable the pan gesture in case the pager is swiping */ - pagerRef?: ForwardedRef; // TODO: For TS migration: Exclude - /** Handles scale changed event */ onScaleChanged?: OnScaleChangedCallback; - - /** Handles scale changed event */ - onTap?: OnTapCallback; }; function MultiGestureCanvas({ @@ -55,16 +44,41 @@ function MultiGestureCanvas({ zoomRange: zoomRangeProp, isActive = true, children, - pagerRef, - shouldDisableTransformationGestures: shouldDisableTransformationGesturesProp, - onTap, - onScaleChanged, + onScaleChanged: onScaleChangedProp, }: MultiGestureCanvasProps) { const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); - const shouldDisableTransformationGesturesFallback = useSharedValue(false); - const shouldDisableTransformationGestures = shouldDisableTransformationGesturesProp ?? shouldDisableTransformationGesturesFallback; + const isSwipingInPagerFallback = useSharedValue(false); + + // If the MultiGestureCanvas used inside a AttachmentCarouselPager, we need to adapt the behaviour based on the pager state + const attachmentCarouselPagerContext = useContext(AttachmentCarouselPagerContext); + const { + onTap, + onScaleChanged: onScaleChangedContext, + isPagerScrolling: isPagerSwiping, + pagerRef, + } = useMemo( + () => + attachmentCarouselPagerContext ?? { + onTap: () => {}, + onScaleChanged: () => {}, + pagerRef: undefined, + isPagerScrolling: isSwipingInPagerFallback, + }, + [attachmentCarouselPagerContext, isSwipingInPagerFallback], + ); + + /** + * Calls the onScaleChanged callback from the both props and the pager context + */ + const onScaleChanged = useCallback( + (newScale: number) => { + onScaleChangedProp?.(newScale); + onScaleChangedContext(newScale); + }, + [onScaleChangedContext, onScaleChangedProp], + ); const zoomRange = useMemo( () => ({ @@ -112,6 +126,8 @@ function MultiGestureCanvas({ const reset = useWorkletCallback((animated: boolean, callback?: () => void) => { stopAnimation(); + pinchScale.value = 1; + if (animated) { offsetX.value = withSpring(0, SPRING_CONFIG); offsetY.value = withSpring(0, SPRING_CONFIG); @@ -139,7 +155,7 @@ function MultiGestureCanvas({ callback(); }); - const {singleTapGesture: baseSingleTapGesture, doubleTapGesture} = useTapGestures({ + const {singleTapGesture: basicSingleTapGesture, doubleTapGesture} = useTapGestures({ canvasSize, contentSize, minContentScale, @@ -152,9 +168,8 @@ function MultiGestureCanvas({ stopAnimation, onScaleChanged, onTap, - shouldDisableTransformationGestures, }); - const singleTapGesture = baseSingleTapGesture.requireExternalGestureToFail(doubleTapGesture, panGestureRef); + const singleTapGesture = basicSingleTapGesture.requireExternalGestureToFail(doubleTapGesture, panGestureRef); const panGestureSimultaneousList = useMemo( () => (pagerRef === undefined ? [singleTapGesture, doubleTapGesture] : [pagerRef as unknown as Exclude, singleTapGesture, doubleTapGesture]), @@ -170,8 +185,8 @@ function MultiGestureCanvas({ offsetY, panTranslateX, panTranslateY, + isPagerSwiping, stopAnimation, - shouldDisableTransformationGestures, }) .simultaneousWithExternalGesture(...panGestureSimultaneousList) .withRef(panGestureRef); @@ -185,9 +200,9 @@ function MultiGestureCanvas({ pinchTranslateX, pinchTranslateY, pinchScale, + isPagerSwiping, stopAnimation, onScaleChanged, - shouldDisableTransformationGestures, }).simultaneousWithExternalGesture(panGesture, singleTapGesture, doubleTapGesture); // Trigger a reset when the canvas gets inactive, but only if it was already mounted before diff --git a/src/components/MultiGestureCanvas/types.ts b/src/components/MultiGestureCanvas/types.ts index 40fcc1462a09..bbd8f69e6947 100644 --- a/src/components/MultiGestureCanvas/types.ts +++ b/src/components/MultiGestureCanvas/types.ts @@ -31,7 +31,7 @@ type MultiGestureCanvasVariables = { zoomRange: ZoomRange; minContentScale: number; maxContentScale: number; - shouldDisableTransformationGestures: SharedValue; + isPagerSwiping: SharedValue; zoomScale: SharedValue; totalScale: SharedValue; pinchScale: SharedValue; @@ -43,8 +43,8 @@ type MultiGestureCanvasVariables = { pinchTranslateY: SharedValue; stopAnimation: () => void; reset: (animated: boolean, callback: () => void) => void; - onTap: OnTapCallback | undefined; + onTap: OnTapCallback; onScaleChanged: OnScaleChangedCallback | undefined; }; -export type {CanvasSize, ContentSize, ZoomRange, OnScaleChangedCallback, OnTapCallback, MultiGestureCanvasVariables}; +export type {CanvasSize, ContentSize, ZoomRange, OnScaleChangedCallback, MultiGestureCanvasVariables}; diff --git a/src/components/MultiGestureCanvas/usePanGesture.ts b/src/components/MultiGestureCanvas/usePanGesture.ts index a3f9c7d62df0..8a646446fad4 100644 --- a/src/components/MultiGestureCanvas/usePanGesture.ts +++ b/src/components/MultiGestureCanvas/usePanGesture.ts @@ -13,21 +13,10 @@ const PAN_DECAY_DECELARATION = 0.9915; type UsePanGestureProps = Pick< MultiGestureCanvasVariables, - 'canvasSize' | 'contentSize' | 'zoomScale' | 'totalScale' | 'offsetX' | 'offsetY' | 'panTranslateX' | 'panTranslateY' | 'shouldDisableTransformationGestures' | 'stopAnimation' + 'canvasSize' | 'contentSize' | 'zoomScale' | 'totalScale' | 'offsetX' | 'offsetY' | 'panTranslateX' | 'panTranslateY' | 'isPagerSwiping' | 'stopAnimation' >; -const usePanGesture = ({ - canvasSize, - contentSize, - zoomScale, - totalScale, - offsetX, - offsetY, - panTranslateX, - panTranslateY, - shouldDisableTransformationGestures, - stopAnimation, -}: UsePanGestureProps): PanGesture => { +const usePanGesture = ({canvasSize, contentSize, zoomScale, totalScale, offsetX, offsetY, panTranslateX, panTranslateY, isPagerSwiping, stopAnimation}: UsePanGestureProps): PanGesture => { // The content size after fitting it to the canvas and zooming const zoomedContentWidth = useDerivedValue(() => contentSize.width * totalScale.value, [contentSize.width]); const zoomedContentHeight = useDerivedValue(() => contentSize.height * totalScale.value, [contentSize.height]); @@ -128,7 +117,7 @@ const usePanGesture = ({ // eslint-disable-next-line @typescript-eslint/naming-convention .onTouchesMove((_evt, state) => { // We only allow panning when the content is zoomed in - if (zoomScale.value <= 1 || shouldDisableTransformationGestures.value) { + if (zoomScale.value <= 1 || isPagerSwiping.value) { return; } @@ -158,7 +147,7 @@ const usePanGesture = ({ panTranslateY.value = 0; // If we are swiping (in the pager), we don't want to return to boundaries - if (shouldDisableTransformationGestures.value) { + if (isPagerSwiping.value) { return; } diff --git a/src/components/MultiGestureCanvas/usePinchGesture.ts b/src/components/MultiGestureCanvas/usePinchGesture.ts index 74a2326748a1..2ff375dc7edd 100644 --- a/src/components/MultiGestureCanvas/usePinchGesture.ts +++ b/src/components/MultiGestureCanvas/usePinchGesture.ts @@ -8,17 +8,7 @@ import type {MultiGestureCanvasVariables} from './types'; type UsePinchGestureProps = Pick< MultiGestureCanvasVariables, - | 'canvasSize' - | 'zoomScale' - | 'zoomRange' - | 'offsetX' - | 'offsetY' - | 'pinchTranslateX' - | 'pinchTranslateY' - | 'pinchScale' - | 'shouldDisableTransformationGestures' - | 'stopAnimation' - | 'onScaleChanged' + 'canvasSize' | 'zoomScale' | 'zoomRange' | 'offsetX' | 'offsetY' | 'pinchTranslateX' | 'pinchTranslateY' | 'pinchScale' | 'isPagerSwiping' | 'stopAnimation' | 'onScaleChanged' >; const usePinchGesture = ({ @@ -30,7 +20,7 @@ const usePinchGesture = ({ pinchTranslateX: totalPinchTranslateX, pinchTranslateY: totalPinchTranslateY, pinchScale, - shouldDisableTransformationGestures, + isPagerSwiping, stopAnimation, onScaleChanged, }: UsePinchGestureProps): PinchGesture => { @@ -97,11 +87,10 @@ const usePinchGesture = ({ const pinchGesture = Gesture.Pinch() .enabled(pinchEnabled) - // The first argument is not used, but must be defined // eslint-disable-next-line @typescript-eslint/naming-convention .onTouchesDown((_evt, state) => { // We don't want to activate pinch gesture when we are swiping in the pager - if (!shouldDisableTransformationGestures.value) { + if (!isPagerSwiping.value) { return; } diff --git a/src/components/MultiGestureCanvas/useTapGestures.ts b/src/components/MultiGestureCanvas/useTapGestures.ts index a28333725d6e..ce67f11a91c8 100644 --- a/src/components/MultiGestureCanvas/useTapGestures.ts +++ b/src/components/MultiGestureCanvas/useTapGestures.ts @@ -9,19 +9,7 @@ import * as MultiGestureCanvasUtils from './utils'; type UseTapGesturesProps = Pick< MultiGestureCanvasVariables, - | 'canvasSize' - | 'contentSize' - | 'minContentScale' - | 'maxContentScale' - | 'offsetX' - | 'offsetY' - | 'pinchScale' - | 'zoomScale' - | 'shouldDisableTransformationGestures' - | 'reset' - | 'stopAnimation' - | 'onScaleChanged' - | 'onTap' + 'canvasSize' | 'contentSize' | 'minContentScale' | 'maxContentScale' | 'offsetX' | 'offsetY' | 'pinchScale' | 'zoomScale' | 'reset' | 'stopAnimation' | 'onScaleChanged' | 'onTap' >; const useTapGestures = ({ @@ -35,7 +23,6 @@ const useTapGestures = ({ zoomScale, reset, stopAnimation, - shouldDisableTransformationGestures, onScaleChanged, onTap, }: UseTapGesturesProps): {singleTapGesture: TapGesture; doubleTapGesture: TapGesture} => { @@ -120,15 +107,6 @@ const useTapGestures = ({ ); const doubleTapGesture = Gesture.Tap() - // The first argument is not used, but must be defined - // eslint-disable-next-line @typescript-eslint/naming-convention - .onTouchesDown((_evt, state) => { - if (!shouldDisableTransformationGestures.value) { - return; - } - - state.fail(); - }) .numberOfTaps(2) .maxDelay(150) .maxDistance(20)