fix: dispatch pop early when screen is closed with gesture (#336)

fixes #267
This commit is contained in:
Satyajit Sahoo
2020-02-02 23:56:05 +01:00
committed by GitHub
parent 343320783f
commit 3d937d1e65
7 changed files with 44 additions and 19 deletions

View File

@@ -133,6 +133,8 @@ export default class Card extends React.Component<Props> {
private interactionHandle: number | undefined;
private pendingGestureCallback: number | undefined;
private animate = ({
closing,
velocity,
@@ -161,6 +163,8 @@ export default class Card extends React.Component<Props> {
this.setPointerEventsEnabled(!closing);
this.handleStartInteraction();
clearTimeout(this.pendingGestureCallback);
onTransitionStart?.({ closing });
animation(gesture, {
...spec.config,
@@ -171,6 +175,8 @@ export default class Card extends React.Component<Props> {
}).start(({ finished }) => {
this.handleEndInteraction();
clearTimeout(this.pendingGestureCallback);
if (finished) {
if (closing) {
onClose();
@@ -221,6 +227,7 @@ export default class Card extends React.Component<Props> {
}: PanGestureHandlerGestureEvent) => {
const {
layout,
onClose,
onGestureBegin,
onGestureCanceled,
onGestureEnd,
@@ -266,6 +273,16 @@ export default class Card extends React.Component<Props> {
: false;
this.animate({ closing, velocity });
if (closing) {
// We call onClose with a delay to make sure that the animation has already started
// This will make sure that the state update caused by this doesn't affect start of animation
this.pendingGestureCallback = (setTimeout(
onClose,
32
) as any) as number;
}
onGestureEnd?.();
break;
}

View File

@@ -7,7 +7,6 @@ import {
ViewStyle,
Platform,
} from 'react-native';
import { StackNavigationState } from '@react-navigation/routers';
import { Route, useTheme } from '@react-navigation/native';
import { Props as HeaderContainerProps } from '../Header/HeaderContainer';
import Card from './Card';
@@ -23,7 +22,6 @@ type Props = TransitionPreset & {
gesture: Animated.Value;
previousScene?: Scene<Route<string>>;
scene: Scene<Route<string>>;
state: StackNavigationState;
safeAreaInsetTop: number;
safeAreaInsetRight: number;
safeAreaInsetBottom: number;
@@ -34,6 +32,7 @@ type Props = TransitionPreset & {
getPreviousRoute: (props: {
route: Route<string>;
}) => Route<string> | undefined;
getFocusedRoute: () => Route<string>;
renderHeader: (props: HeaderContainerProps) => React.ReactNode;
renderScene: (props: { route: Route<string> }) => React.ReactNode;
onOpenRoute: (props: { route: Route<string> }) => void;
@@ -78,6 +77,7 @@ function CardContainer({
gestureResponseDistance,
gestureVelocityImpact,
getPreviousRoute,
getFocusedRoute,
headerMode,
headerShown,
headerStyleInterpolator,
@@ -101,7 +101,6 @@ function CardContainer({
safeAreaInsetRight,
safeAreaInsetTop,
scene,
state,
transitionSpec,
}: Props) {
React.useEffect(() => {
@@ -203,8 +202,8 @@ function CardContainer({
layout,
insets,
scenes: [previousScene, scene],
state,
getPreviousRoute,
getFocusedRoute,
gestureDirection,
styleInterpolator: headerStyleInterpolator,
onContentHeightChange: onHeaderHeightChange,

View File

@@ -398,6 +398,12 @@ export default class CardStack extends React.Component<Props, State> {
});
};
private getFocusedRoute = () => {
const { state } = this.props;
return state.routes[state.index];
};
render() {
const {
mode,
@@ -581,7 +587,6 @@ export default class CardStack extends React.Component<Props, State> {
gesture={gesture}
scene={scene}
previousScene={previousScene}
state={state}
safeAreaInsetTop={safeAreaInsetTop}
safeAreaInsetRight={safeAreaInsetRight}
safeAreaInsetBottom={safeAreaInsetBottom}
@@ -596,6 +601,7 @@ export default class CardStack extends React.Component<Props, State> {
headerHeight={headerHeights[route.key]}
onHeaderHeightChange={this.handleHeaderLayout}
getPreviousRoute={getPreviousRoute}
getFocusedRoute={this.getFocusedRoute}
headerMode={headerMode}
headerShown={headerShown}
headerTransparent={headerTransparent}
@@ -619,8 +625,8 @@ export default class CardStack extends React.Component<Props, State> {
layout,
insets: { top, right, bottom, left },
scenes,
state,
getPreviousRoute,
getFocusedRoute: this.getFocusedRoute,
onContentHeightChange: this.handleHeaderLayout,
gestureDirection:
focusedOptions.gestureDirection !== undefined

View File

@@ -314,14 +314,18 @@ class StackView extends React.Component<Props, State> {
source: route.key,
target: state.key,
});
} else {
// We need to clean up any state tracking the route and pop it immediately
this.setState(state => ({
routes: state.routes.filter(r => r.key !== route.key),
openingRouteKeys: state.openingRouteKeys.filter(
key => key !== route.key
),
closingRouteKeys: state.closingRouteKeys.filter(
key => key !== route.key
),
}));
}
// We need to clean up any state tracking the route and pop it immediately
this.setState(state => ({
routes: state.routes.filter(r => r.key !== route.key),
openingRouteKeys: state.openingRouteKeys.filter(key => key !== route.key),
closingRouteKeys: state.closingRouteKeys.filter(key => key !== route.key),
}));
};
private handleTransitionStart = (