Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import {BaseNavigationContainer, NavigationIndependentTree} from '@react-navigation/core';
import type {StackCardInterpolationProps} from '@react-navigation/stack';
import React, {useEffect, useState} from 'react';
import React, {useCallback, useEffect, useState} from 'react';
import {StyleSheet, View} from 'react-native';
import Animated, {useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated';
import Animated, {cancelAnimation, useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated';
import {scheduleOnRN} from 'react-native-worklets';
import {DefaultCancelConfirmModal} from '@components/MultifactorAuthentication/components/Modals';
import {useMultifactorAuthentication, useMultifactorAuthenticationActions, useMultifactorAuthenticationState} from '@components/MultifactorAuthentication/Context';
import type {MultifactorAuthenticationModalNavigatorInternalParamList} from '@components/MultifactorAuthentication/mfaNavigation';
Expand All @@ -15,8 +16,8 @@ import useSidePanelState from '@hooks/useSidePanelState';
import useTheme from '@hooks/useTheme';
import useThemePreference from '@hooks/useThemePreference';
import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
import getNavigationBaseTheme from '@libs/Navigation/getNavigationBaseTheme';
import Navigation from '@libs/Navigation/Navigation';
import createPlatformStackNavigator from '@libs/Navigation/PlatformStackNavigation/createPlatformStackNavigator';
import Animations from '@libs/Navigation/PlatformStackNavigation/navigationOptions/animation';
import Presentation from '@libs/Navigation/PlatformStackNavigation/navigationOptions/presentation';
Expand Down Expand Up @@ -87,6 +88,9 @@ function MultifactorAuthenticationModalNavigator() {

const [phase, setPhase] = useState<Phase>(isModalOpen ? 'open' : 'closed');
const backdropProgress = useSharedValue(0);
const panelTranslateX = useSharedValue(0);
const {windowWidth} = useWindowDimensions();
const panelWidth = shouldUseNarrowLayout ? windowWidth : variables.sideBarWidth;
const modalCardStyleInterpolator = useModalCardStyleInterpolator();
const CancelConfirmModal = scenario?.modals.cancelConfirmation ?? DefaultCancelConfirmModal;

Expand All @@ -108,30 +112,44 @@ function MultifactorAuthenticationModalNavigator() {
},
};

const finishClose = useCallback(() => {
resetMfaNavigation();
setPhase('closed');
dispatch({type: 'RESET'});
}, [dispatch]);

useEffect(() => {
if (phase === 'open') {
panelTranslateX.set(0);
backdropProgress.set(withTiming(1, {duration: CONST.ANIMATED_TRANSITION}));
return;
}
if (phase !== 'closing') {
return;
}
if (mfaNavigationRef.isReady() && mfaNavigationRef.canGoBack()) {
mfaNavigationRef.goBack();
}
// Slide the whole overlay out as one unit and fade the backdrop in parallel. Animating a single
// screen (e.g. via goBack) would reveal screens still on the stack beneath the outcome screen
// before the overlay unmounts.
backdropProgress.set(withTiming(0, {duration: CONST.ANIMATED_TRANSITION}));
const handle = Navigation.runAfterUpcomingTransition(() => {
resetMfaNavigation();
setPhase('closed');
dispatch({type: 'RESET'});
});
return () => handle.cancel();
}, [phase, backdropProgress, dispatch]);
panelTranslateX.set(
withTiming(panelWidth, {duration: CONST.ANIMATED_TRANSITION}, (finished) => {
if (!finished) {
return;
}
scheduleOnRN(finishClose);
}),
);
return () => cancelAnimation(panelTranslateX);
}, [phase, backdropProgress, panelTranslateX, panelWidth, finishClose]);

const backdropAnimatedStyle = useAnimatedStyle(() => ({
opacity: backdropProgress.get() * variables.overlayOpacity,
}));

const panelAnimatedStyle = useAnimatedStyle(() => ({
transform: [{translateX: panelTranslateX.get()}],
}));

if (phase === 'closed') {
return null;
}
Expand All @@ -153,7 +171,9 @@ function MultifactorAuthenticationModalNavigator() {
/>
</Animated.View>
)}
<View style={[styles.pAbsolute, styles.r0, styles.h100, styles.overflowHidden, shouldUseNarrowLayout ? styles.w100 : {width: variables.sideBarWidth}]}>
<Animated.View
style={[styles.pAbsolute, styles.r0, styles.h100, styles.overflowHidden, shouldUseNarrowLayout ? styles.w100 : {width: variables.sideBarWidth}, panelAnimatedStyle]}
>
{isStackReadyToMount && (
<NavigationIndependentTree>
<BaseNavigationContainer
Expand Down Expand Up @@ -215,7 +235,7 @@ function MultifactorAuthenticationModalNavigator() {
</BaseNavigationContainer>
</NavigationIndependentTree>
)}
</View>
</Animated.View>
<CancelConfirmModal
isVisible={isCancelConfirmVisible}
onConfirm={confirmCancel}
Expand Down
Loading