Skip to content

Commit

Permalink
Finish review improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
piaskowyk committed Dec 13, 2023
1 parent 524a461 commit cf37301
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 33 deletions.
8 changes: 5 additions & 3 deletions Example/src/screens/SwipeBackAnimation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,11 @@ const App = (): JSX.Element => (
<Stack.Screen
name="ScreenB"
component={ScreenB}
options={{
goBackGesture: 'twoDimensionalSwipe',
}}
options={
{
// goBackGesture: 'twoDimensionalSwipe',
}
}
/>
<Stack.Screen name="ScreenC" component={ScreenC} />
</Stack.Navigator>
Expand Down
2 changes: 1 addition & 1 deletion ios/RNSModule.mm
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ - (RNSScreenStackView *)getScreenStackView:(NSNumber *)reactTag
#else
screenTags = @[ topScreen.reactTag, belowTopScreen.reactTag ];
#endif // RCT_NEW_ARCH_ENABLED
[stackView startScreenTransition];
}
[stackView startScreenTransition];
return screenTags;
}

Expand Down
13 changes: 6 additions & 7 deletions ios/RNSScreenStack.mm
Original file line number Diff line number Diff line change
Expand Up @@ -664,13 +664,12 @@ - (void)dismissOnReload
}
BOOL shouldCancelDismiss = [self shouldCancelDismissFromView:(RNSScreenView *)fromVC.view
toView:(RNSScreenView *)toVC.view];
if (_customAnimation ||
screen != nil &&
// when preventing the native dismiss with back button, we have to return the animator.
// Also, we need to return the animator when full width swiping even if the animation is not custom,
// otherwise the screen will be just popped immediately due to no animation
((operation == UINavigationControllerOperationPop && shouldCancelDismiss) || _isFullWidthSwiping ||
[RNSScreenStackAnimator isCustomAnimation:screen.stackAnimation])) {
if (screen != nil &&
// when preventing the native dismiss with back button, we have to return the animator.
// Also, we need to return the animator when full width swiping even if the animation is not custom,
// otherwise the screen will be just popped immediately due to no animation
((operation == UINavigationControllerOperationPop && shouldCancelDismiss) || _isFullWidthSwiping ||
[RNSScreenStackAnimator isCustomAnimation:screen.stackAnimation] || _customAnimation)) {
return [[RNSScreenStackAnimator alloc] initWithOperation:operation];
}
return nil;
Expand Down
72 changes: 52 additions & 20 deletions src/gesture-handler/GestureDetector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ const TransitionHandler = ({
stackRef,
goBackGesture,
screenEdgeGesture,
transitionAnimation: userTransitionAnimation,
transitionAnimation: customTransitionAnimation,
screensRefHolder,
currentRouteKey,
}: GestureProviderProps) => {
Expand All @@ -105,8 +105,8 @@ const TransitionHandler = ({
const startingGesturePosition = useSharedValue(DefaultEvent);
const canPerformUpdates = useSharedValue(false);
let transitionAnimation = ScreenTransition.SwipeRight;
if (userTransitionAnimation) {
transitionAnimation = userTransitionAnimation;
if (customTransitionAnimation) {
transitionAnimation = customTransitionAnimation;
if (!goBackGesture) {
throw new Error(
'[RNScreens] You have to specify `goBackGesture` when using `transitionAnimation`.'
Expand Down Expand Up @@ -194,11 +194,10 @@ const TransitionHandler = ({
canPerformUpdates.value = true;
}

function onUpdate(event: GestureUpdateEvent<PanGestureHandlerEventPayload>) {
function checkBoundaries(
event: GestureUpdateEvent<PanGestureHandlerEventPayload>
) {
'worklet';
if (!canPerformUpdates.value) {
return;
}
if (goBackGesture === 'swipeRight' && event.translationX < 0) {
event.translationX = 0;
} else if (goBackGesture === 'swipeLeft' && event.translationX > 0) {
Expand All @@ -208,6 +207,12 @@ const TransitionHandler = ({
} else if (goBackGesture === 'swipeUp' && event.translationY > 0) {
event.translationY = 0;
}
}

function computeProgress(
event: GestureUpdateEvent<PanGestureHandlerEventPayload>
) {
'worklet';
let progress = 0;
if (goBackGesture === 'swipeRight') {
const screenWidth = screenTransitionConfig.value.screenDimensions.width;
Expand Down Expand Up @@ -237,21 +242,28 @@ const TransitionHandler = ({
const progressY = Math.abs(event.translationY / screenHeight / 2);
progress = Math.max(progressX, progressY);
}
sharedEvent.value = event;
const stackTag = screenTransitionConfig.value.stackTag;
RNScreensTurboModule.updateTransition(stackTag, progress);
return progress;
}

function onEnd(event: GestureUpdateEvent<PanGestureHandlerEventPayload>) {
function onUpdate(event: GestureUpdateEvent<PanGestureHandlerEventPayload>) {
'worklet';
if (!canPerformUpdates.value) {
return;
}
const screenSize = screenTransitionConfig.value.screenDimensions;
const distanceX = event.translationX + event.velocityX * 0.3;
const distanceY = event.translationY + event.velocityY * 0.3;
const requiredXDistance = screenSize.width / 2;
const requiredYDistance = screenSize.height / 2;
checkBoundaries(event);
const progress = computeProgress(event);
sharedEvent.value = event;
const stackTag = screenTransitionConfig.value.stackTag;
RNScreensTurboModule.updateTransition(stackTag, progress);
}

function checkIfTransitionCancelled(
distanceX: number,
requiredXDistance: number,
distanceY: number,
requiredYDistance: number
) {
'worklet';
let isTransitionCanceled = false;
if (goBackGesture === 'swipeRight') {
isTransitionCanceled = distanceX < requiredXDistance;
Expand All @@ -270,6 +282,25 @@ const TransitionHandler = ({
const isCanceledVertically = Math.abs(distanceY) < requiredYDistance;
isTransitionCanceled = isCanceledHorizontally && isCanceledVertically;
}
return isTransitionCanceled;
}

function onEnd(event: GestureUpdateEvent<PanGestureHandlerEventPayload>) {
'worklet';
if (!canPerformUpdates.value) {
return;
}
const screenSize = screenTransitionConfig.value.screenDimensions;
const distanceX = event.translationX + event.velocityX * 0.3;
const distanceY = event.translationY + event.velocityY * 0.3;
const requiredXDistance = screenSize.width / 2;
const requiredYDistance = screenSize.height / 2;
const isTransitionCanceled = checkIfTransitionCancelled(
distanceX,
requiredXDistance,
distanceY,
requiredYDistance
);
const stackTag = screenTransitionConfig.value.stackTag;
screenTransitionConfig.value.onFinishAnimation = () => {
RNScreensTurboModule.finishTransition(stackTag, isTransitionCanceled);
Expand All @@ -285,22 +316,23 @@ const TransitionHandler = ({

if (screenEdgeGesture) {
const HIT_SLOP_SIZE = 50;
const ACTIVATION_DISTANCE = 30;
if (goBackGesture === 'swipeRight') {
panGesture = panGesture
.activeOffsetX(20)
.activeOffsetX(ACTIVATION_DISTANCE)
.hitSlop({ left: 0, top: 0, width: HIT_SLOP_SIZE });
} else if (goBackGesture === 'swipeLeft') {
panGesture = panGesture
.activeOffsetX(-20)
.activeOffsetX(-ACTIVATION_DISTANCE)
.hitSlop({ right: 0, top: 0, width: HIT_SLOP_SIZE });
} else if (goBackGesture === 'swipeDown') {
panGesture = panGesture
.activeOffsetY(20)
.activeOffsetY(ACTIVATION_DISTANCE)
.hitSlop({ top: 0, height: Dimensions.get('window').height * 0.2 });
// workaround, because we don't have access to header height
} else if (goBackGesture === 'swipeUp') {
panGesture = panGesture
.activeOffsetY(-20)
.activeOffsetY(-ACTIVATION_DISTANCE)
.hitSlop({ bottom: 0, height: HIT_SLOP_SIZE });
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/native-stack/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ export type NativeStackNavigationOptions = {

goBackGesture?: GoBackGesture;
transitionAnimation?: AnimatedScreenTransition;
screenEdgeGesture?: false;
screenEdgeGesture?: boolean;
};

export type NativeStackNavigatorProps =
Expand Down Expand Up @@ -521,5 +521,5 @@ export type GestureProviderProps = PropsWithChildren<{
currentRouteKey: string;
goBackGesture: GoBackGesture | undefined;
transitionAnimation: AnimatedScreenTransition | undefined;
screenEdgeGesture: false | undefined;
screenEdgeGesture: boolean | undefined;
}>;

0 comments on commit cf37301

Please sign in to comment.