From 937f9ee91c485759c492b9dec532914ffa40375b Mon Sep 17 00:00:00 2001 From: Mo Gorhom Date: Tue, 20 Jul 2021 22:11:06 +0100 Subject: [PATCH] refactor: allow closing animation to be interrupted --- src/components/bottomSheet/BottomSheet.tsx | 51 +++++++++++-------- .../bottomSheetModal/BottomSheetModal.tsx | 6 +-- .../BottomSheetModalProvider.tsx | 4 +- src/types.d.ts | 4 +- 4 files changed, 37 insertions(+), 28 deletions(-) diff --git a/src/components/bottomSheet/BottomSheet.tsx b/src/components/bottomSheet/BottomSheet.tsx index 3e3d455c4..2f24cbc5f 100644 --- a/src/components/bottomSheet/BottomSheet.tsx +++ b/src/components/bottomSheet/BottomSheet.tsx @@ -256,6 +256,7 @@ const BottomSheetComponent = forwardRef( ); }); const isInTemporaryPosition = useSharedValue(false); + const isForcedClosing = useSharedValue(false); // gesture const animatedContentGestureState = useSharedValue( @@ -480,11 +481,6 @@ const BottomSheetComponent = forwardRef( return currentIndex; }, [android_keyboardInputMode]); - const isSheetClosing = useDerivedValue( - () => - animatedNextPosition.value === animatedClosedPosition.value && - animatedAnimationState.value === ANIMATION_STATE.RUNNING - ); //#endregion //#region private methods @@ -597,11 +593,14 @@ const BottomSheetComponent = forwardRef( ); const stopAnimation = useWorkletCallback(() => { cancelAnimation(animatedPosition); + isForcedClosing.value = false; animatedAnimationSource.value = ANIMATION_SOURCE.NONE; animatedAnimationState.value = ANIMATION_STATE.STOPPED; }, [animatedPosition, animatedAnimationState, animatedAnimationSource]); const animateToPositionCompleted = useWorkletCallback( function animateToPositionCompleted(isFinished: boolean) { + isForcedClosing.value = false; + if (!isFinished) { return; } @@ -719,12 +718,12 @@ const BottomSheetComponent = forwardRef( /** * exit method if : * - already animating to next position. - * - sheet is closing. + * - sheet is forced closing. */ if ( index === animatedNextPositionIndex.value || nextPosition === animatedNextPosition.value || - isSheetClosing.value + isForcedClosing.value ) { return; } @@ -744,7 +743,7 @@ const BottomSheetComponent = forwardRef( [ animateToPosition, isInTemporaryPosition, - isSheetClosing, + isForcedClosing, animatedSnapPoints, animatedNextPosition, animatedNextPositionIndex, @@ -776,11 +775,11 @@ const BottomSheetComponent = forwardRef( /** * exit method if : * - already animating to next position. - * - sheet is closing. + * - sheet is forced closing. */ if ( nextPosition === animatedNextPosition.value || - isSheetClosing.value + isForcedClosing.value ) { return; } @@ -801,14 +800,17 @@ const BottomSheetComponent = forwardRef( animateToPosition, bottomInset, topInset, - isSheetClosing, + isForcedClosing, animatedContainerHeight, animatedPosition, ] ); const handleClose = useCallback( function handleClose( - animationConfigs?: Animated.WithSpringConfig | Animated.WithTimingConfig + animationConfigs?: + | Animated.WithSpringConfig + | Animated.WithTimingConfig, + force?: boolean ) { print({ component: BottomSheet.name, @@ -820,20 +822,25 @@ const BottomSheetComponent = forwardRef( /** * exit method if : * - already animating to next position. - * - sheet is closing. + * - sheet is forced closing. */ if ( nextPosition === animatedNextPosition.value || - isSheetClosing.value + isForcedClosing.value ) { return; } /** - * reset temporary position boolean. + * reset temporary position variable. */ isInTemporaryPosition.value = false; + /** + * set force closing variable. + */ + isForcedClosing.value = force === undefined ? false : force; + runOnUI(animateToPosition)( nextPosition, 0, @@ -843,7 +850,7 @@ const BottomSheetComponent = forwardRef( }, [ animateToPosition, - isSheetClosing, + isForcedClosing, isInTemporaryPosition, animatedNextPosition, animatedClosedPosition, @@ -864,12 +871,12 @@ const BottomSheetComponent = forwardRef( /** * exit method if : * - already animating to next position. - * - sheet is closing. + * - sheet is forced closing. */ if ( snapPoints.length - 1 === animatedNextPositionIndex.value || nextPosition === animatedNextPosition.value || - isSheetClosing.value + isForcedClosing.value ) { return; } @@ -889,7 +896,7 @@ const BottomSheetComponent = forwardRef( [ animateToPosition, isInTemporaryPosition, - isSheetClosing, + isForcedClosing, animatedSnapPoints, animatedNextPosition, animatedNextPositionIndex, @@ -909,12 +916,12 @@ const BottomSheetComponent = forwardRef( /** * exit method if : * - already animating to next position. - * - sheet is closing. + * - sheet is forced closing. */ if ( animatedNextPositionIndex.value === 0 || nextPosition === animatedNextPosition.value || - isSheetClosing.value + isForcedClosing.value ) { return; } @@ -933,7 +940,7 @@ const BottomSheetComponent = forwardRef( }, [ animateToPosition, - isSheetClosing, + isForcedClosing, isInTemporaryPosition, animatedSnapPoints, animatedNextPosition, diff --git a/src/components/bottomSheetModal/BottomSheetModal.tsx b/src/components/bottomSheetModal/BottomSheetModal.tsx index f9955c4d8..ff18759e7 100644 --- a/src/components/bottomSheetModal/BottomSheetModal.tsx +++ b/src/components/bottomSheetModal/BottomSheetModal.tsx @@ -169,8 +169,8 @@ const BottomSheetModalComponent = forwardRef< }, [key, index, stackBehavior, mount, ref, mountSheet] ); - const handleDismiss = useCallback( - function handleDismiss(...args) { + const handleDismiss = useCallback( + function handleDismiss(animationConfigs) { print({ component: BottomSheetModal.name, method: handleDismiss.name, @@ -195,7 +195,7 @@ const BottomSheetModalComponent = forwardRef< } willUnmountSheet(key); forcedDismissed.current = true; - bottomSheetRef.current?.close(...args); + bottomSheetRef.current?.close(animationConfigs, true); }, [willUnmountSheet, unmount, key, enablePanDownToClose] ); diff --git a/src/components/bottomSheetModalProvider/BottomSheetModalProvider.tsx b/src/components/bottomSheetModalProvider/BottomSheetModalProvider.tsx index ae5e35270..6cba45efa 100644 --- a/src/components/bottomSheetModalProvider/BottomSheetModalProvider.tsx +++ b/src/components/bottomSheetModalProvider/BottomSheetModalProvider.tsx @@ -140,12 +140,12 @@ const BottomSheetModalProviderWrapper = ({ item => item.key === key ); if (sheetToBeDismissed) { - sheetToBeDismissed.ref.current.dismiss(true); + sheetToBeDismissed.ref.current.dismiss(); } }, []); const handleDismissAll = useCallback(() => { sheetsQueueRef.current.map(item => { - item.ref.current.dismiss(true); + item.ref.current.dismiss(); }); }, []); //#endregion diff --git a/src/types.d.ts b/src/types.d.ts index 0aa6d905f..133b90cc0 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -50,12 +50,14 @@ export interface BottomSheetMethods { /** * Close the bottom sheet. * @param animationConfigs snap animation configs. + * @param force prevent any interruptions till sheet is closed. * * @see {Animated.WithSpringConfig} * @see {Animated.WithTimingConfig} */ close: ( - animationConfigs?: Animated.WithSpringConfig | Animated.WithTimingConfig + animationConfigs?: Animated.WithSpringConfig | Animated.WithTimingConfig, + force?: boolean ) => void; }