From 98cac0c9f16c7f927128ffd8a2b55362c73c7ad8 Mon Sep 17 00:00:00 2001 From: kirillzyusko Date: Wed, 14 Feb 2024 17:25:40 +0100 Subject: [PATCH 1/8] feat: swipe to dismiss (initial changes) --- src/components/MultiGestureCanvas/index.tsx | 2 + src/components/MultiGestureCanvas/types.ts | 1 + .../MultiGestureCanvas/usePanGesture.ts | 57 ++++++++++++++++--- 3 files changed, 53 insertions(+), 7 deletions(-) diff --git a/src/components/MultiGestureCanvas/index.tsx b/src/components/MultiGestureCanvas/index.tsx index a7eca6baa18f..6d00384cee1b 100644 --- a/src/components/MultiGestureCanvas/index.tsx +++ b/src/components/MultiGestureCanvas/index.tsx @@ -102,6 +102,7 @@ function MultiGestureCanvas({ const panTranslateX = useSharedValue(0); const panTranslateY = useSharedValue(0); + const isSwipingDownToClose = useSharedValue(false); const panGestureRef = useRef(Gesture.Pan()); const pinchScale = useSharedValue(1); @@ -186,6 +187,7 @@ function MultiGestureCanvas({ panTranslateX, panTranslateY, isPagerSwiping, + isSwipingDownToClose, stopAnimation, }) .simultaneousWithExternalGesture(...panGestureSimultaneousList) diff --git a/src/components/MultiGestureCanvas/types.ts b/src/components/MultiGestureCanvas/types.ts index bbd8f69e6947..00e7e3017dab 100644 --- a/src/components/MultiGestureCanvas/types.ts +++ b/src/components/MultiGestureCanvas/types.ts @@ -32,6 +32,7 @@ type MultiGestureCanvasVariables = { minContentScale: number; maxContentScale: number; isPagerSwiping: SharedValue; + isSwipingDownToClose: SharedValue; zoomScale: SharedValue; totalScale: SharedValue; pinchScale: SharedValue; diff --git a/src/components/MultiGestureCanvas/usePanGesture.ts b/src/components/MultiGestureCanvas/usePanGesture.ts index 8a646446fad4..026cf53d5598 100644 --- a/src/components/MultiGestureCanvas/usePanGesture.ts +++ b/src/components/MultiGestureCanvas/usePanGesture.ts @@ -13,19 +13,37 @@ const PAN_DECAY_DECELARATION = 0.9915; type UsePanGestureProps = Pick< MultiGestureCanvasVariables, - 'canvasSize' | 'contentSize' | 'zoomScale' | 'totalScale' | 'offsetX' | 'offsetY' | 'panTranslateX' | 'panTranslateY' | 'isPagerSwiping' | 'stopAnimation' + 'canvasSize' | 'contentSize' | 'zoomScale' | 'totalScale' | 'offsetX' | 'offsetY' | 'panTranslateX' | 'panTranslateY' | 'isPagerSwiping' | 'isSwipingDownToClose' | 'stopAnimation' >; -const usePanGesture = ({canvasSize, contentSize, zoomScale, totalScale, offsetX, offsetY, panTranslateX, panTranslateY, isPagerSwiping, stopAnimation}: UsePanGestureProps): PanGesture => { +const usePanGesture = ({ + canvasSize, + contentSize, + zoomScale, + totalScale, + offsetX, + offsetY, + panTranslateX, + panTranslateY, + isPagerSwiping, + isSwipingDownToClose, + 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]); + // Used to track previous touch position for the "swipe down to close" gesture + const previousTouch = useSharedValue<{x: number; y: number} | null>(null); + // Velocity of the pan gesture // We need to keep track of the velocity to properly phase out/decay the pan animation const panVelocityX = useSharedValue(0); const panVelocityY = useSharedValue(0); + // Disable "swipe down to close" gesture when content is bigger than the canvas + const enableSwipeDownToClose = useDerivedValue(() => canvasSize.height < zoomedContentHeight.value, [canvasSize.height]); + // Calculates bounds of the scaled content // Can we pan left/right/up/down // Can be used to limit gesture or implementing tension effect @@ -117,11 +135,31 @@ const usePanGesture = ({canvasSize, contentSize, zoomScale, totalScale, offsetX, // 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 || isPagerSwiping.value) { - return; + if (zoomScale.value > 1) { + state.activate(); + } + + // TODO: this needs tuning to work properly + if (!isPagerSwiping.value && zoomScale.value === 1 && previousTouch.value != null) { + const velocityX = Math.abs(_evt.allTouches[0].x - previousTouch.value.x); + const velocityY = _evt.allTouches[0].y - previousTouch.value.y; + + if (Math.abs(velocityY) > velocityX && velocityY > 20) { + state.activate(); + + isSwipingDownToClose.value = true; + previousTouch.value = null; + + return; + } } - state.activate(); + if (previousTouch.value == null) { + previousTouch.value = { + x: _evt.allTouches[0].x, + y: _evt.allTouches[0].y, + }; + } }) .onStart(() => { stopAnimation(); @@ -136,8 +174,13 @@ const usePanGesture = ({canvasSize, contentSize, zoomScale, totalScale, offsetX, panVelocityX.value = evt.velocityX; panVelocityY.value = evt.velocityY; - panTranslateX.value += evt.changeX; - panTranslateY.value += evt.changeY; + if (!isSwipingDownToClose.value) { + panTranslateX.value += evt.changeX; + } + + if (enableSwipeDownToClose.value || isSwipingDownToClose.value) { + panTranslateY.value += evt.changeY; + } }) .onEnd(() => { // Add pan translation to total offset and reset gesture variables From 34aa114b610cb28a7a4e06f1e13224ad12b0b132 Mon Sep 17 00:00:00 2001 From: kirillzyusko Date: Thu, 15 Feb 2024 20:34:16 +0100 Subject: [PATCH 2/8] feat: swipeable card (in all states properly) --- .../MultiGestureCanvas/usePanGesture.ts | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/components/MultiGestureCanvas/usePanGesture.ts b/src/components/MultiGestureCanvas/usePanGesture.ts index 026cf53d5598..661dabadbb75 100644 --- a/src/components/MultiGestureCanvas/usePanGesture.ts +++ b/src/components/MultiGestureCanvas/usePanGesture.ts @@ -121,7 +121,9 @@ const usePanGesture = ({ } } else { // Animated back to the boundary - offsetY.value = withSpring(clampedOffset.y, SPRING_CONFIG); + offsetY.value = withSpring(clampedOffset.y, SPRING_CONFIG, () => { + isSwipingDownToClose.value = false; + }); } // Reset velocity variables after we finished the pan gesture @@ -132,17 +134,19 @@ const usePanGesture = ({ const panGesture = Gesture.Pan() .manualActivation(true) .averageTouches(true) - // eslint-disable-next-line @typescript-eslint/naming-convention - .onTouchesMove((_evt, state) => { + .onTouchesUp(() => { + previousTouch.value = null; + }) + .onTouchesMove((evt, state) => { // We only allow panning when the content is zoomed in if (zoomScale.value > 1) { state.activate(); } // TODO: this needs tuning to work properly - if (!isPagerSwiping.value && zoomScale.value === 1 && previousTouch.value != null) { - const velocityX = Math.abs(_evt.allTouches[0].x - previousTouch.value.x); - const velocityY = _evt.allTouches[0].y - previousTouch.value.y; + if (!isPagerSwiping.value && zoomScale.value === 1 && previousTouch.value !== null) { + const velocityX = Math.abs(evt.allTouches[0].x - previousTouch.value.x); + const velocityY = evt.allTouches[0].y - previousTouch.value.y; if (Math.abs(velocityY) > velocityX && velocityY > 20) { state.activate(); @@ -154,10 +158,10 @@ const usePanGesture = ({ } } - if (previousTouch.value == null) { + if (previousTouch.value === null) { previousTouch.value = { - x: _evt.allTouches[0].x, - y: _evt.allTouches[0].y, + x: evt.allTouches[0].x, + y: evt.allTouches[0].y, }; } }) @@ -186,8 +190,11 @@ const usePanGesture = ({ // Add pan translation to total offset and reset gesture variables offsetX.value += panTranslateX.value; offsetY.value += panTranslateY.value; + + // Reset pan gesture variables panTranslateX.value = 0; panTranslateY.value = 0; + previousTouch.value = null; // If we are swiping (in the pager), we don't want to return to boundaries if (isPagerSwiping.value) { From e395ed660d319b07efaab30fdcdac5f4157d59f1 Mon Sep 17 00:00:00 2001 From: kirillzyusko Date: Tue, 20 Feb 2024 19:35:57 +0100 Subject: [PATCH 3/8] feat: actually close carousel if gesture down happens --- .../Pager/AttachmentCarouselPagerContext.ts | 1 + .../AttachmentCarousel/Pager/index.tsx | 6 ++-- .../AttachmentCarousel/index.native.js | 5 +++ src/components/MultiGestureCanvas/index.tsx | 3 ++ src/components/MultiGestureCanvas/types.ts | 4 +++ .../MultiGestureCanvas/usePanGesture.ts | 35 +++++++++++++++---- 6 files changed, 46 insertions(+), 8 deletions(-) diff --git a/src/components/Attachments/AttachmentCarousel/Pager/AttachmentCarouselPagerContext.ts b/src/components/Attachments/AttachmentCarousel/Pager/AttachmentCarouselPagerContext.ts index 270e0b04909c..ac08591c2812 100644 --- a/src/components/Attachments/AttachmentCarousel/Pager/AttachmentCarouselPagerContext.ts +++ b/src/components/Attachments/AttachmentCarousel/Pager/AttachmentCarouselPagerContext.ts @@ -9,6 +9,7 @@ type AttachmentCarouselPagerContextValue = { isScrollEnabled: SharedValue; onTap: () => void; onScaleChanged: (scale: number) => void; + onSwipeDown: () => void; }; const AttachmentCarouselPagerContext = createContext(null); diff --git a/src/components/Attachments/AttachmentCarousel/Pager/index.tsx b/src/components/Attachments/AttachmentCarousel/Pager/index.tsx index 490afb6614ac..d5b8ba2d36f4 100644 --- a/src/components/Attachments/AttachmentCarousel/Pager/index.tsx +++ b/src/components/Attachments/AttachmentCarousel/Pager/index.tsx @@ -31,9 +31,10 @@ type AttachmentCarouselPagerProps = { initialIndex: number; onPageSelected: () => void; onRequestToggleArrows: (showArrows?: boolean) => void; + onClose: () => void; }; -function AttachmentCarouselPager({items, renderItem, initialIndex, onPageSelected, onRequestToggleArrows}: AttachmentCarouselPagerProps, ref: ForwardedRef) { +function AttachmentCarouselPager({items, renderItem, initialIndex, onPageSelected, onRequestToggleArrows, onClose}: AttachmentCarouselPagerProps, ref: ForwardedRef) { const styles = useThemeStyles(); const pagerRef = useRef(null); @@ -98,9 +99,10 @@ function AttachmentCarouselPager({items, renderItem, initialIndex, onPageSelecte isPagerScrolling, isScrollEnabled, onTap: handleTap, + onSwipeDown: onClose, onScaleChanged: handleScaleChange, }), - [isPagerScrolling, isScrollEnabled, handleTap, handleScaleChange], + [isPagerScrolling, isScrollEnabled, handleTap, handleScaleChange, onClose], ); const animatedProps = useAnimatedProps(() => ({ diff --git a/src/components/Attachments/AttachmentCarousel/index.native.js b/src/components/Attachments/AttachmentCarousel/index.native.js index fa24ccd0ef53..cd437740900b 100644 --- a/src/components/Attachments/AttachmentCarousel/index.native.js +++ b/src/components/Attachments/AttachmentCarousel/index.native.js @@ -103,6 +103,10 @@ function AttachmentCarousel({report, reportActions, parentReportActions, source, [setShouldShowArrows], ); + const goBack = useCallback(() => { + Navigation.goBack(); + }, []); + /** * Defines how a single attachment should be rendered * @param {{ reportActionID: String, isAuthTokenRequired: Boolean, source: String, file: { name: String }, hasBeenFlagged: Boolean }} item @@ -152,6 +156,7 @@ function AttachmentCarousel({report, reportActions, parentReportActions, source, initialIndex={page} onRequestToggleArrows={toggleArrows} onPageSelected={({nativeEvent: {position: newPage}}) => updatePage(newPage)} + onClose={goBack} ref={pagerRef} /> diff --git a/src/components/MultiGestureCanvas/index.tsx b/src/components/MultiGestureCanvas/index.tsx index 6d00384cee1b..1e89c81c0058 100644 --- a/src/components/MultiGestureCanvas/index.tsx +++ b/src/components/MultiGestureCanvas/index.tsx @@ -55,6 +55,7 @@ function MultiGestureCanvas({ const attachmentCarouselPagerContext = useContext(AttachmentCarouselPagerContext); const { onTap, + onSwipeDown, onScaleChanged: onScaleChangedContext, isPagerScrolling: isPagerSwiping, pagerRef, @@ -62,6 +63,7 @@ function MultiGestureCanvas({ () => attachmentCarouselPagerContext ?? { onTap: () => {}, + onSwipeDown: () => {}, onScaleChanged: () => {}, pagerRef: undefined, isPagerScrolling: isSwipingInPagerFallback, @@ -189,6 +191,7 @@ function MultiGestureCanvas({ isPagerSwiping, isSwipingDownToClose, stopAnimation, + onSwipeDown, }) .simultaneousWithExternalGesture(...panGestureSimultaneousList) .withRef(panGestureRef); diff --git a/src/components/MultiGestureCanvas/types.ts b/src/components/MultiGestureCanvas/types.ts index 00e7e3017dab..aa090a86fa37 100644 --- a/src/components/MultiGestureCanvas/types.ts +++ b/src/components/MultiGestureCanvas/types.ts @@ -24,6 +24,9 @@ type OnScaleChangedCallback = (zoomScale: number) => void; /** Triggered when the canvas is tapped (single tap) */ type OnTapCallback = () => void; +/** Triggered when the swipe down gesture on canvas occurs */ +type OnSwipeDownCallback = () => void; + /** Types used of variables used within the MultiGestureCanvas component and it's hooks */ type MultiGestureCanvasVariables = { canvasSize: CanvasSize; @@ -46,6 +49,7 @@ type MultiGestureCanvasVariables = { reset: (animated: boolean, callback: () => void) => void; onTap: OnTapCallback; onScaleChanged: OnScaleChangedCallback | undefined; + onSwipeDown: OnSwipeDownCallback; }; export type {CanvasSize, ContentSize, ZoomRange, OnScaleChangedCallback, MultiGestureCanvasVariables}; diff --git a/src/components/MultiGestureCanvas/usePanGesture.ts b/src/components/MultiGestureCanvas/usePanGesture.ts index 661dabadbb75..3d82a1306175 100644 --- a/src/components/MultiGestureCanvas/usePanGesture.ts +++ b/src/components/MultiGestureCanvas/usePanGesture.ts @@ -1,7 +1,7 @@ /* eslint-disable no-param-reassign */ import type {PanGesture} from 'react-native-gesture-handler'; import {Gesture} from 'react-native-gesture-handler'; -import {useDerivedValue, useSharedValue, useWorkletCallback, withDecay, withSpring} from 'react-native-reanimated'; +import {runOnJS, useDerivedValue, useSharedValue, useWorkletCallback, withDecay, withSpring} from 'react-native-reanimated'; import {SPRING_CONFIG} from './constants'; import type {MultiGestureCanvasVariables} from './types'; import * as MultiGestureCanvasUtils from './utils'; @@ -13,7 +13,18 @@ const PAN_DECAY_DECELARATION = 0.9915; type UsePanGestureProps = Pick< MultiGestureCanvasVariables, - 'canvasSize' | 'contentSize' | 'zoomScale' | 'totalScale' | 'offsetX' | 'offsetY' | 'panTranslateX' | 'panTranslateY' | 'isPagerSwiping' | 'isSwipingDownToClose' | 'stopAnimation' + | 'canvasSize' + | 'contentSize' + | 'zoomScale' + | 'totalScale' + | 'offsetX' + | 'offsetY' + | 'panTranslateX' + | 'panTranslateY' + | 'isPagerSwiping' + | 'isSwipingDownToClose' + | 'stopAnimation' + | 'onSwipeDown' >; const usePanGesture = ({ @@ -28,6 +39,7 @@ const usePanGesture = ({ isPagerSwiping, isSwipingDownToClose, stopAnimation, + onSwipeDown, }: UsePanGestureProps): PanGesture => { // The content size after fitting it to the canvas and zooming const zoomedContentWidth = useDerivedValue(() => contentSize.width * totalScale.value, [contentSize.width]); @@ -120,10 +132,21 @@ const usePanGesture = ({ }); } } else { - // Animated back to the boundary - offsetY.value = withSpring(clampedOffset.y, SPRING_CONFIG, () => { - isSwipingDownToClose.value = false; - }); + const finalTranslateY = offsetY.value + panVelocityY.value * 0.2; + + // TODO: calculate these values (250/500) programmatically + if (finalTranslateY > 250) { + offsetY.value = withSpring(500, SPRING_CONFIG, () => { + isSwipingDownToClose.value = false; + }); + + runOnJS(onSwipeDown)(); + } else { + // Animated back to the boundary + offsetY.value = withSpring(clampedOffset.y, SPRING_CONFIG, () => { + isSwipingDownToClose.value = false; + }); + } } // Reset velocity variables after we finished the pan gesture From 2b7ce7d97c40c64b82af7160a1b7d67b3a28c4b3 Mon Sep 17 00:00:00 2001 From: kirillzyusko Date: Wed, 21 Feb 2024 18:12:20 +0100 Subject: [PATCH 4/8] fix: post merge fix --- src/components/MultiGestureCanvas/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/MultiGestureCanvas/types.ts b/src/components/MultiGestureCanvas/types.ts index d56a210c2cda..ceb29a0333b4 100644 --- a/src/components/MultiGestureCanvas/types.ts +++ b/src/components/MultiGestureCanvas/types.ts @@ -52,4 +52,4 @@ type MultiGestureCanvasVariables = { onSwipeDown: OnSwipeDownCallback; }; -export type {CanvasSize, ContentSize, ZoomRange, OnScaleChangedCallback, OnTapCallback, MultiGestureCanvasVariables}; +export type {CanvasSize, ContentSize, ZoomRange, OnScaleChangedCallback, OnTapCallback, MultiGestureCanvasVariables, OnSwipeDownCallback}; From 25418abc7c6a5d25847336fc4f54eee20490d854 Mon Sep 17 00:00:00 2001 From: kirillzyusko Date: Wed, 21 Feb 2024 18:26:26 +0100 Subject: [PATCH 5/8] fix: post merge fix (2) --- src/components/Lightbox/index.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/Lightbox/index.tsx b/src/components/Lightbox/index.tsx index 36cb175e3c45..69fa0d5e6e41 100644 --- a/src/components/Lightbox/index.tsx +++ b/src/components/Lightbox/index.tsx @@ -59,6 +59,7 @@ function Lightbox({isAuthTokenRequired = false, uri, onScaleChanged: onScaleChan activePage, onTap, onScaleChanged: onScaleChangedContext, + onSwipeDown, pagerRef, } = useMemo(() => { if (attachmentCarouselPagerContext === null) { @@ -70,6 +71,7 @@ function Lightbox({isAuthTokenRequired = false, uri, onScaleChanged: onScaleChan activePage: 0, onTap: () => {}, onScaleChanged: () => {}, + onSwipeDown: () => {}, pagerRef: undefined, }; } @@ -212,6 +214,7 @@ function Lightbox({isAuthTokenRequired = false, uri, onScaleChanged: onScaleChan shouldDisableTransformationGestures={isPagerScrolling} onTap={onTap} onScaleChanged={scaleChange} + onSwipeDown={onSwipeDown} > Date: Wed, 21 Feb 2024 18:55:01 +0100 Subject: [PATCH 6/8] fix: don't close if swipe down occurs when image zoomed in --- src/components/MultiGestureCanvas/usePanGesture.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/MultiGestureCanvas/usePanGesture.ts b/src/components/MultiGestureCanvas/usePanGesture.ts index 04de6bd1912a..8075b089410e 100644 --- a/src/components/MultiGestureCanvas/usePanGesture.ts +++ b/src/components/MultiGestureCanvas/usePanGesture.ts @@ -135,7 +135,7 @@ const usePanGesture = ({ const finalTranslateY = offsetY.value + panVelocityY.value * 0.2; // TODO: calculate these values (250/500) programmatically - if (finalTranslateY > 250) { + if (finalTranslateY > 250 && zoomScale.value <= 1) { offsetY.value = withSpring(500, SPRING_CONFIG, () => { isSwipingDownToClose.value = false; }); From 20f51ca271a566727a61a40774837fb11468f75e Mon Sep 17 00:00:00 2001 From: kirillzyusko Date: Wed, 21 Feb 2024 19:45:50 +0100 Subject: [PATCH 7/8] fix: calculate snap points based on screen size --- src/components/MultiGestureCanvas/usePanGesture.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/components/MultiGestureCanvas/usePanGesture.ts b/src/components/MultiGestureCanvas/usePanGesture.ts index 8075b089410e..298d62ee6b9d 100644 --- a/src/components/MultiGestureCanvas/usePanGesture.ts +++ b/src/components/MultiGestureCanvas/usePanGesture.ts @@ -1,4 +1,5 @@ /* eslint-disable no-param-reassign */ +import {Dimensions} from 'react-native'; import type {PanGesture} from 'react-native-gesture-handler'; import {Gesture} from 'react-native-gesture-handler'; import {runOnJS, useDerivedValue, useSharedValue, useWorkletCallback, withDecay, withSpring} from 'react-native-reanimated'; @@ -10,6 +11,9 @@ import * as MultiGestureCanvasUtils from './utils'; // We're using a "withDecay" animation to smoothly phase out the pan animation // https://docs.swmansion.com/react-native-reanimated/docs/animations/withDecay/ const PAN_DECAY_DECELARATION = 0.9915; +const SCREEN_HEIGHT = Dimensions.get('screen').height; +const SNAP_POINT = SCREEN_HEIGHT / 4; +const SNAP_POINT_HIDDEN = SCREEN_HEIGHT / 1.2; type UsePanGestureProps = Pick< MultiGestureCanvasVariables, @@ -134,9 +138,8 @@ const usePanGesture = ({ } else { const finalTranslateY = offsetY.value + panVelocityY.value * 0.2; - // TODO: calculate these values (250/500) programmatically - if (finalTranslateY > 250 && zoomScale.value <= 1) { - offsetY.value = withSpring(500, SPRING_CONFIG, () => { + if (finalTranslateY > SNAP_POINT && zoomScale.value <= 1) { + offsetY.value = withSpring(SNAP_POINT_HIDDEN, SPRING_CONFIG, () => { isSwipingDownToClose.value = false; }); From 44efead61ab65abdf57edb3286552b5f4be4dc55 Mon Sep 17 00:00:00 2001 From: kirillzyusko Date: Thu, 22 Feb 2024 13:41:10 +0100 Subject: [PATCH 8/8] fix: CI checks --- .../Attachments/AttachmentCarousel/Pager/index.tsx | 7 +++++-- src/components/MultiGestureCanvas/index.tsx | 2 +- src/components/MultiGestureCanvas/types.ts | 2 +- src/components/MultiGestureCanvas/usePanGesture.ts | 4 +++- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/components/Attachments/AttachmentCarousel/Pager/index.tsx b/src/components/Attachments/AttachmentCarousel/Pager/index.tsx index fd5e177400e4..33d9f20b5e57 100644 --- a/src/components/Attachments/AttachmentCarousel/Pager/index.tsx +++ b/src/components/Attachments/AttachmentCarousel/Pager/index.tsx @@ -42,12 +42,15 @@ type AttachmentCarouselPagerProps = { * @param showArrows If set, it will show/hide the arrows. If not set, it will toggle the arrows. */ onRequestToggleArrows: (showArrows?: boolean) => void; - + /** A callback that is called when swipe-down-to-close gesture happens */ onClose: () => void; }; -function AttachmentCarouselPager({items, activeSource, initialPage, onPageSelected, onRequestToggleArrows, onClose}: AttachmentCarouselPagerProps, ref: ForwardedRef) { +function AttachmentCarouselPager( + {items, activeSource, initialPage, onPageSelected, onRequestToggleArrows, onClose}: AttachmentCarouselPagerProps, + ref: ForwardedRef, +) { const styles = useThemeStyles(); const pagerRef = useRef(null); diff --git a/src/components/MultiGestureCanvas/index.tsx b/src/components/MultiGestureCanvas/index.tsx index 940e71adb54f..9430ac9f2a19 100644 --- a/src/components/MultiGestureCanvas/index.tsx +++ b/src/components/MultiGestureCanvas/index.tsx @@ -10,7 +10,7 @@ import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; import type ChildrenProps from '@src/types/utils/ChildrenProps'; import {DEFAULT_ZOOM_RANGE, SPRING_CONFIG, ZOOM_RANGE_BOUNCE_FACTORS} from './constants'; -import type {CanvasSize, ContentSize, OnScaleChangedCallback, OnTapCallback, ZoomRange, OnSwipeDownCallback} from './types'; +import type {CanvasSize, ContentSize, OnScaleChangedCallback, OnSwipeDownCallback, OnTapCallback, ZoomRange} from './types'; import usePanGesture from './usePanGesture'; import usePinchGesture from './usePinchGesture'; import useTapGestures from './useTapGestures'; diff --git a/src/components/MultiGestureCanvas/types.ts b/src/components/MultiGestureCanvas/types.ts index ceb29a0333b4..fbb2f3deb88c 100644 --- a/src/components/MultiGestureCanvas/types.ts +++ b/src/components/MultiGestureCanvas/types.ts @@ -49,7 +49,7 @@ type MultiGestureCanvasVariables = { reset: (animated: boolean, callback: () => void) => void; onTap: OnTapCallback | undefined; onScaleChanged: OnScaleChangedCallback | undefined; - onSwipeDown: OnSwipeDownCallback; + onSwipeDown: OnSwipeDownCallback | undefined; }; export type {CanvasSize, ContentSize, ZoomRange, OnScaleChangedCallback, OnTapCallback, MultiGestureCanvasVariables, OnSwipeDownCallback}; diff --git a/src/components/MultiGestureCanvas/usePanGesture.ts b/src/components/MultiGestureCanvas/usePanGesture.ts index 298d62ee6b9d..97843e118871 100644 --- a/src/components/MultiGestureCanvas/usePanGesture.ts +++ b/src/components/MultiGestureCanvas/usePanGesture.ts @@ -143,7 +143,9 @@ const usePanGesture = ({ isSwipingDownToClose.value = false; }); - runOnJS(onSwipeDown)(); + if (onSwipeDown) { + runOnJS(onSwipeDown)(); + } } else { // Animated back to the boundary offsetY.value = withSpring(clampedOffset.y, SPRING_CONFIG, () => {