mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-01-24 21:08:15 +08:00
768 lines
25 KiB
Diff
768 lines
25 KiB
Diff
diff -Naur ../../node_modules/@react-navigation/stack/src/index.tsx src/vendor/index.tsx
|
|
--- ../../node_modules/@react-navigation/stack/src/index.tsx 2020-10-26 16:07:00.000000000 +0100
|
|
+++ src/vendor/index.tsx 2020-10-26 16:08:35.000000000 +0100
|
|
@@ -3,11 +3,6 @@
|
|
import * as TransitionSpecs from './TransitionConfigs/TransitionSpecs';
|
|
import * as TransitionPresets from './TransitionConfigs/TransitionPresets';
|
|
|
|
-/**
|
|
- * Navigators
|
|
- */
|
|
-export { default as createStackNavigator } from './navigators/createStackNavigator';
|
|
-
|
|
export const Assets = [
|
|
// eslint-disable-next-line import/no-commonjs
|
|
require('./views/assets/back-icon.png'),
|
|
@@ -49,9 +44,10 @@
|
|
* Types
|
|
*/
|
|
export type {
|
|
- StackNavigationOptions,
|
|
- StackNavigationProp,
|
|
- StackScreenProps,
|
|
+ NavigationStackState,
|
|
+ StackNavigationProp as NavigationStackProp,
|
|
+ StackNavigationOptions as NavigationStackOptions,
|
|
+ StackNavigationConfig as NavigationStackConfig,
|
|
StackHeaderProps,
|
|
StackHeaderLeftButtonProps,
|
|
StackHeaderTitleProps,
|
|
diff -Naur ../../node_modules/@react-navigation/stack/src/navigators/createStackNavigator.tsx src/vendor/navigators/createStackNavigator.tsx
|
|
--- ../../node_modules/@react-navigation/stack/src/navigators/createStackNavigator.tsx 2020-10-26 16:07:00.000000000 +0100
|
|
+++ src/vendor/navigators/createStackNavigator.tsx 1970-01-01 01:00:00.000000000 +0100
|
|
@@ -1,101 +0,0 @@
|
|
-import * as React from 'react';
|
|
-import { Platform } from 'react-native';
|
|
-import {
|
|
- useNavigationBuilder,
|
|
- createNavigatorFactory,
|
|
- DefaultNavigatorOptions,
|
|
- EventArg,
|
|
- StackRouter,
|
|
- StackRouterOptions,
|
|
- StackNavigationState,
|
|
- StackActions,
|
|
- ParamListBase,
|
|
- StackActionHelpers,
|
|
-} from '@react-navigation/native';
|
|
-import StackView from '../views/Stack/StackView';
|
|
-import type {
|
|
- StackNavigationConfig,
|
|
- StackNavigationOptions,
|
|
- StackNavigationEventMap,
|
|
-} from '../types';
|
|
-
|
|
-type Props = DefaultNavigatorOptions<StackNavigationOptions> &
|
|
- StackRouterOptions &
|
|
- StackNavigationConfig;
|
|
-
|
|
-function StackNavigator({
|
|
- initialRouteName,
|
|
- children,
|
|
- screenOptions,
|
|
- ...rest
|
|
-}: Props) {
|
|
- const defaultOptions = {
|
|
- gestureEnabled: Platform.OS === 'ios',
|
|
- animationEnabled:
|
|
- Platform.OS !== 'web' &&
|
|
- Platform.OS !== 'windows' &&
|
|
- Platform.OS !== 'macos',
|
|
- };
|
|
-
|
|
- const { state, descriptors, navigation } = useNavigationBuilder<
|
|
- StackNavigationState<ParamListBase>,
|
|
- StackRouterOptions,
|
|
- StackActionHelpers<ParamListBase>,
|
|
- StackNavigationOptions,
|
|
- StackNavigationEventMap
|
|
- >(StackRouter, {
|
|
- initialRouteName,
|
|
- children,
|
|
- screenOptions:
|
|
- typeof screenOptions === 'function'
|
|
- ? (...args) => ({
|
|
- ...defaultOptions,
|
|
- ...screenOptions(...args),
|
|
- })
|
|
- : {
|
|
- ...defaultOptions,
|
|
- ...screenOptions,
|
|
- },
|
|
- });
|
|
-
|
|
- React.useEffect(
|
|
- () =>
|
|
- navigation.addListener?.('tabPress', (e) => {
|
|
- const isFocused = navigation.isFocused();
|
|
-
|
|
- // Run the operation in the next frame so we're sure all listeners have been run
|
|
- // This is necessary to know if preventDefault() has been called
|
|
- requestAnimationFrame(() => {
|
|
- if (
|
|
- state.index > 0 &&
|
|
- isFocused &&
|
|
- !(e as EventArg<'tabPress', true>).defaultPrevented
|
|
- ) {
|
|
- // When user taps on already focused tab and we're inside the tab,
|
|
- // reset the stack to replicate native behaviour
|
|
- navigation.dispatch({
|
|
- ...StackActions.popToTop(),
|
|
- target: state.key,
|
|
- });
|
|
- }
|
|
- });
|
|
- }),
|
|
- [navigation, state.index, state.key]
|
|
- );
|
|
-
|
|
- return (
|
|
- <StackView
|
|
- {...rest}
|
|
- state={state}
|
|
- descriptors={descriptors}
|
|
- navigation={navigation}
|
|
- />
|
|
- );
|
|
-}
|
|
-
|
|
-export default createNavigatorFactory<
|
|
- StackNavigationState<ParamListBase>,
|
|
- StackNavigationOptions,
|
|
- StackNavigationEventMap,
|
|
- typeof StackNavigator
|
|
->(StackNavigator);
|
|
diff -Naur ../../node_modules/@react-navigation/stack/src/types.tsx src/vendor/types.tsx
|
|
--- ../../node_modules/@react-navigation/stack/src/types.tsx 2020-10-26 16:07:00.000000000 +0100
|
|
+++ src/vendor/types.tsx 2020-10-26 16:13:50.000000000 +0100
|
|
@@ -8,15 +8,29 @@
|
|
} from 'react-native';
|
|
import type { EdgeInsets } from 'react-native-safe-area-context';
|
|
import type {
|
|
+ NavigationRoute,
|
|
+ NavigationState,
|
|
+ NavigationScreenProp,
|
|
NavigationProp,
|
|
- ParamListBase,
|
|
- Descriptor,
|
|
- Route,
|
|
- NavigationHelpers,
|
|
- StackNavigationState,
|
|
- StackActionHelpers,
|
|
- RouteProp,
|
|
-} from '@react-navigation/native';
|
|
+ NavigationParams,
|
|
+ NavigationNavigateAction,
|
|
+ NavigationAction,
|
|
+ NavigationEventCallback,
|
|
+ NavigationEventSubscription,
|
|
+ NavigationDescriptor,
|
|
+} from 'react-navigation';
|
|
+
|
|
+// @ts-ignore
|
|
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
+export type Route<T extends string> = NavigationRoute;
|
|
+
|
|
+export type NavigationStackState = NavigationState;
|
|
+
|
|
+export type NavigationStackEventName =
|
|
+ | 'willFocus'
|
|
+ | 'didFocus'
|
|
+ | 'willBlur'
|
|
+ | 'didBlur';
|
|
|
|
export type StackNavigationEventMap = {
|
|
/**
|
|
@@ -41,30 +55,29 @@
|
|
gestureCancel: { data: undefined };
|
|
};
|
|
|
|
-export type StackNavigationHelpers = NavigationHelpers<
|
|
- ParamListBase,
|
|
- StackNavigationEventMap
|
|
-> &
|
|
- StackActionHelpers<ParamListBase>;
|
|
+export type StackNavigationHelpers = NavigationProp<NavigationStackState>;
|
|
|
|
export type StackNavigationProp<
|
|
- ParamList extends ParamListBase,
|
|
- RouteName extends keyof ParamList = string
|
|
-> = NavigationProp<
|
|
- ParamList,
|
|
- RouteName,
|
|
- StackNavigationState<ParamList>,
|
|
- StackNavigationOptions,
|
|
- StackNavigationEventMap
|
|
-> &
|
|
- StackActionHelpers<ParamList>;
|
|
-
|
|
-export type StackScreenProps<
|
|
- ParamList extends ParamListBase,
|
|
- RouteName extends keyof ParamList = string
|
|
-> = {
|
|
- navigation: StackNavigationProp<ParamList, RouteName>;
|
|
- route: RouteProp<ParamList, RouteName>;
|
|
+ State = NavigationRoute,
|
|
+ Params = NavigationParams
|
|
+> = NavigationScreenProp<State, Params> & {
|
|
+ push: (
|
|
+ routeName: string,
|
|
+ params?: NavigationParams,
|
|
+ action?: NavigationNavigateAction
|
|
+ ) => boolean;
|
|
+ replace: (
|
|
+ routeName: string,
|
|
+ params?: NavigationParams,
|
|
+ action?: NavigationNavigateAction
|
|
+ ) => boolean;
|
|
+ reset: (actions: NavigationAction[], index: number) => boolean;
|
|
+ pop: (n?: number, params?: { immediate?: boolean }) => boolean;
|
|
+ popToTop: (params?: { immediate?: boolean }) => boolean;
|
|
+ addListener: (
|
|
+ event: NavigationStackEventName,
|
|
+ callback: NavigationEventCallback
|
|
+ ) => NavigationEventSubscription;
|
|
};
|
|
|
|
export type Layout = { width: number; height: number };
|
|
@@ -241,24 +254,27 @@
|
|
/**
|
|
* Navigation prop for the header.
|
|
*/
|
|
- navigation: StackNavigationProp<ParamListBase>;
|
|
+ navigation: StackNavigationProp;
|
|
/**
|
|
* Interpolated styles for various elements in the header.
|
|
*/
|
|
styleInterpolator: StackHeaderStyleInterpolator;
|
|
};
|
|
|
|
-export type StackDescriptor = Descriptor<
|
|
- ParamListBase,
|
|
- string,
|
|
- StackNavigationState<ParamListBase>,
|
|
- StackNavigationOptions
|
|
+export type StackDescriptor = NavigationDescriptor<
|
|
+ NavigationParams,
|
|
+ StackNavigationOptions,
|
|
+ StackNavigationProp
|
|
>;
|
|
|
|
export type StackDescriptorMap = {
|
|
[key: string]: StackDescriptor;
|
|
};
|
|
|
|
+export type TransitionCallbackProps = {
|
|
+ closing: boolean;
|
|
+};
|
|
+
|
|
export type StackNavigationOptions = StackHeaderOptions &
|
|
Partial<TransitionPreset> & {
|
|
/**
|
|
@@ -352,6 +368,8 @@
|
|
* Defaults to `false` for the last screen when mode='modal', otherwise `true`.
|
|
*/
|
|
detachPreviousScreen?: boolean;
|
|
+ onTransitionStart?: (props: TransitionCallbackProps) => void;
|
|
+ onTransitionEnd?: (props: TransitionCallbackProps) => void;
|
|
};
|
|
|
|
export type StackNavigationConfig = {
|
|
@@ -365,7 +383,7 @@
|
|
/**
|
|
* Whether inactive screens should be detached from the view hierarchy to save memory.
|
|
* Make sure to call `enableScreens` from `react-native-screens` to make it work.
|
|
- * Defaults to `true`.
|
|
+ * Defaults to `true` on Android, `false` on iOS.
|
|
*/
|
|
detachInactiveScreens?: boolean;
|
|
};
|
|
diff -Naur ../../node_modules/@react-navigation/stack/src/utils/PreviousSceneContext.tsx src/vendor/utils/PreviousSceneContext.tsx
|
|
--- ../../node_modules/@react-navigation/stack/src/utils/PreviousSceneContext.tsx 2020-10-26 16:07:00.000000000 +0100
|
|
+++ src/vendor/utils/PreviousSceneContext.tsx 2020-10-26 16:08:40.000000000 +0100
|
|
@@ -1,6 +1,5 @@
|
|
import * as React from 'react';
|
|
-import type { Route } from '@react-navigation/native';
|
|
-import type { Scene } from '../types';
|
|
+import type { Route, Scene } from '../types';
|
|
|
|
const PreviousSceneContext = React.createContext<
|
|
Scene<Route<string>> | undefined
|
|
diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/Header.tsx src/vendor/views/Header/Header.tsx
|
|
--- ../../node_modules/@react-navigation/stack/src/views/Header/Header.tsx 2020-10-26 16:07:00.000000000 +0100
|
|
+++ src/vendor/views/Header/Header.tsx 2020-10-26 16:08:40.000000000 +0100
|
|
@@ -1,12 +1,15 @@
|
|
import * as React from 'react';
|
|
-import { StackActions } from '@react-navigation/native';
|
|
+import { Dimensions } from 'react-native';
|
|
+import { StackActions } from 'react-navigation';
|
|
+import { getStatusBarHeight } from 'react-native-iphone-x-helper';
|
|
+
|
|
+import HeaderSegment, { getDefaultHeaderHeight } from './HeaderSegment';
|
|
|
|
-import HeaderSegment from './HeaderSegment';
|
|
import HeaderTitle from './HeaderTitle';
|
|
import debounce from '../../utils/debounce';
|
|
import type { StackHeaderProps, StackHeaderTitleProps } from '../../types';
|
|
|
|
-export default React.memo(function Header(props: StackHeaderProps) {
|
|
+const Header = React.memo(function Header(props: StackHeaderProps) {
|
|
const {
|
|
scene,
|
|
previous,
|
|
@@ -22,7 +25,7 @@
|
|
? options.headerTitle
|
|
: options.title !== undefined
|
|
? options.title
|
|
- : scene.route.name;
|
|
+ : scene.route.routeName;
|
|
|
|
let leftLabel;
|
|
|
|
@@ -38,17 +41,20 @@
|
|
? o.headerTitle
|
|
: o.title !== undefined
|
|
? o.title
|
|
- : previous.route.name;
|
|
+ : previous.route.routeName;
|
|
}
|
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
const goBack = React.useCallback(
|
|
debounce(() => {
|
|
- if (navigation.isFocused() && navigation.canGoBack()) {
|
|
- navigation.dispatch({
|
|
- ...StackActions.pop(),
|
|
- source: scene.route.key,
|
|
- });
|
|
+ const key = navigation.isFirstRouteInParent()
|
|
+ ? // If we're the first route, we're going back to a parent navigator
|
|
+ // So we need to get the key of the route we're nested in
|
|
+ navigation.dangerouslyGetParent()?.state.key
|
|
+ : scene.route.key;
|
|
+
|
|
+ if (key !== undefined) {
|
|
+ navigation.dispatch(StackActions.pop({ key }));
|
|
}
|
|
}, 50),
|
|
[navigation, scene.route.key]
|
|
@@ -64,7 +70,10 @@
|
|
leftLabel={leftLabel}
|
|
headerTitle={
|
|
typeof options.headerTitle !== 'function'
|
|
- ? (props: StackHeaderTitleProps) => <HeaderTitle {...props} />
|
|
+ ? (props: StackHeaderTitleProps) => {
|
|
+ // @ts-ignore
|
|
+ return <HeaderTitle {...props} />;
|
|
+ }
|
|
: options.headerTitle
|
|
}
|
|
onGoBack={previous ? goBack : undefined}
|
|
@@ -72,3 +81,18 @@
|
|
/>
|
|
);
|
|
});
|
|
+
|
|
+Object.defineProperty(Header, 'HEIGHT', {
|
|
+ get() {
|
|
+ console.warn(
|
|
+ "Deprecation in 'createStackNavigator': 'Header.HEIGHT' will be removed in a future version. Use 'useHeaderHeight' or 'HeaderHeightContext' instead"
|
|
+ );
|
|
+
|
|
+ return getDefaultHeaderHeight(
|
|
+ Dimensions.get('window'),
|
|
+ getStatusBarHeight(true)
|
|
+ );
|
|
+ },
|
|
+});
|
|
+
|
|
+export default Header;
|
|
diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/HeaderBackButton.tsx src/vendor/views/Header/HeaderBackButton.tsx
|
|
--- ../../node_modules/@react-navigation/stack/src/views/Header/HeaderBackButton.tsx 2020-10-26 16:07:00.000000000 +0100
|
|
+++ src/vendor/views/Header/HeaderBackButton.tsx 2020-10-26 16:14:24.000000000 +0100
|
|
@@ -8,9 +8,9 @@
|
|
StyleSheet,
|
|
LayoutChangeEvent,
|
|
} from 'react-native';
|
|
-import { useTheme } from '@react-navigation/native';
|
|
import MaskedView from '../MaskedView';
|
|
import TouchableItem from '../TouchableItem';
|
|
+import useTheme from '../../../utils/useTheme';
|
|
import type { StackHeaderLeftButtonProps } from '../../types';
|
|
|
|
type Props = StackHeaderLeftButtonProps;
|
|
diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/HeaderBackground.tsx src/vendor/views/Header/HeaderBackground.tsx
|
|
--- ../../node_modules/@react-navigation/stack/src/views/Header/HeaderBackground.tsx 2020-10-26 16:07:00.000000000 +0100
|
|
+++ src/vendor/views/Header/HeaderBackground.tsx 2020-10-26 16:08:40.000000000 +0100
|
|
@@ -7,7 +7,7 @@
|
|
StyleProp,
|
|
ViewStyle,
|
|
} from 'react-native';
|
|
-import { useTheme } from '@react-navigation/native';
|
|
+import useTheme from '../../../utils/useTheme';
|
|
|
|
type Props = ViewProps & {
|
|
style?: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
|
|
diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/HeaderContainer.tsx src/vendor/views/Header/HeaderContainer.tsx
|
|
--- ../../node_modules/@react-navigation/stack/src/views/Header/HeaderContainer.tsx 2020-10-26 16:07:00.000000000 +0100
|
|
+++ src/vendor/views/Header/HeaderContainer.tsx 2020-10-26 16:15:18.000000000 +0100
|
|
@@ -1,11 +1,6 @@
|
|
import * as React from 'react';
|
|
import { Animated, View, StyleSheet, StyleProp, ViewStyle } from 'react-native';
|
|
-import {
|
|
- NavigationContext,
|
|
- NavigationRouteContext,
|
|
- Route,
|
|
- ParamListBase,
|
|
-} from '@react-navigation/native';
|
|
+import { NavigationContext } from 'react-navigation';
|
|
import type { EdgeInsets } from 'react-native-safe-area-context';
|
|
|
|
import Header from './Header';
|
|
@@ -19,6 +14,7 @@
|
|
import PreviousSceneContext from '../../utils/PreviousSceneContext';
|
|
import type {
|
|
Layout,
|
|
+ Route,
|
|
Scene,
|
|
StackHeaderStyleInterpolator,
|
|
StackNavigationProp,
|
|
@@ -105,9 +101,7 @@
|
|
insets,
|
|
scene,
|
|
previous,
|
|
- navigation: scene.descriptor.navigation as StackNavigationProp<
|
|
- ParamListBase
|
|
- >,
|
|
+ navigation: scene.descriptor.navigation as StackNavigationProp,
|
|
styleInterpolator:
|
|
mode === 'float'
|
|
? isHeaderStatic
|
|
@@ -126,7 +120,7 @@
|
|
key={scene.route.key}
|
|
value={scene.descriptor.navigation}
|
|
>
|
|
- <NavigationRouteContext.Provider value={scene.route}>
|
|
+ <>
|
|
<View
|
|
onLayout={
|
|
onContentHeightChange
|
|
@@ -155,7 +149,7 @@
|
|
>
|
|
{header !== undefined ? header(props) : <Header {...props} />}
|
|
</View>
|
|
- </NavigationRouteContext.Provider>
|
|
+ </>
|
|
</NavigationContext.Provider>
|
|
);
|
|
})}
|
|
diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/HeaderSegment.tsx src/vendor/views/Header/HeaderSegment.tsx
|
|
--- ../../node_modules/@react-navigation/stack/src/views/Header/HeaderSegment.tsx 2020-10-26 16:07:00.000000000 +0100
|
|
+++ src/vendor/views/Header/HeaderSegment.tsx 2020-10-26 16:08:40.000000000 +0100
|
|
@@ -8,7 +8,7 @@
|
|
ViewStyle,
|
|
} from 'react-native';
|
|
import type { EdgeInsets } from 'react-native-safe-area-context';
|
|
-import type { Route } from '@react-navigation/native';
|
|
+import type { NavigationRoute } from 'react-navigation';
|
|
import HeaderBackButton from './HeaderBackButton';
|
|
import HeaderBackground from './HeaderBackground';
|
|
import HeaderShownContext from '../../utils/HeaderShownContext';
|
|
@@ -29,7 +29,7 @@
|
|
onGoBack?: () => void;
|
|
title?: string;
|
|
leftLabel?: string;
|
|
- scene: Scene<Route<string>>;
|
|
+ scene: Scene<NavigationRoute>;
|
|
styleInterpolator: StackHeaderStyleInterpolator;
|
|
};
|
|
|
|
diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/HeaderTitle.tsx src/vendor/views/Header/HeaderTitle.tsx
|
|
--- ../../node_modules/@react-navigation/stack/src/views/Header/HeaderTitle.tsx 2020-10-26 16:07:00.000000000 +0100
|
|
+++ src/vendor/views/Header/HeaderTitle.tsx 2020-10-26 16:14:52.000000000 +0100
|
|
@@ -7,7 +7,7 @@
|
|
StyleProp,
|
|
TextStyle,
|
|
} from 'react-native';
|
|
-import { useTheme } from '@react-navigation/native';
|
|
+import useTheme from '../../../utils/useTheme';
|
|
|
|
type Props = Omit<TextProps, 'style'> & {
|
|
tintColor?: string;
|
|
diff -Naur ../../node_modules/@react-navigation/stack/src/views/Stack/Card.tsx src/vendor/views/Stack/Card.tsx
|
|
--- ../../node_modules/@react-navigation/stack/src/views/Stack/Card.tsx 2020-10-26 16:07:00.000000000 +0100
|
|
+++ src/vendor/views/Stack/Card.tsx 2020-10-26 16:08:40.000000000 +0100
|
|
@@ -162,7 +162,7 @@
|
|
|
|
private interactionHandle: number | undefined;
|
|
|
|
- private pendingGestureCallback: number | undefined;
|
|
+ private pendingGestureCallback: any;
|
|
|
|
private lastToValue: number | undefined;
|
|
|
|
diff -Naur ../../node_modules/@react-navigation/stack/src/views/Stack/CardContainer.tsx src/vendor/views/Stack/CardContainer.tsx
|
|
--- ../../node_modules/@react-navigation/stack/src/views/Stack/CardContainer.tsx 2020-10-26 16:07:00.000000000 +0100
|
|
+++ src/vendor/views/Stack/CardContainer.tsx 2020-10-26 16:08:40.000000000 +0100
|
|
@@ -1,12 +1,13 @@
|
|
import * as React from 'react';
|
|
import { Animated, View, StyleSheet, StyleProp, ViewStyle } from 'react-native';
|
|
-import { Route, useTheme } from '@react-navigation/native';
|
|
import type { Props as HeaderContainerProps } from '../Header/HeaderContainer';
|
|
import Card from './Card';
|
|
import HeaderHeightContext from '../../utils/HeaderHeightContext';
|
|
import HeaderShownContext from '../../utils/HeaderShownContext';
|
|
import PreviousSceneContext from '../../utils/PreviousSceneContext';
|
|
+import useTheme from '../../../utils/useTheme';
|
|
import type {
|
|
+ Route,
|
|
Scene,
|
|
Layout,
|
|
StackHeaderMode,
|
|
diff -Naur ../../node_modules/@react-navigation/stack/src/views/Stack/CardStack.tsx src/vendor/views/Stack/CardStack.tsx
|
|
--- ../../node_modules/@react-navigation/stack/src/views/Stack/CardStack.tsx 2020-10-26 16:07:00.000000000 +0100
|
|
+++ src/vendor/views/Stack/CardStack.tsx 2020-10-26 16:17:14.000000000 +0100
|
|
@@ -7,11 +7,7 @@
|
|
Platform,
|
|
} from 'react-native';
|
|
import type { EdgeInsets } from 'react-native-safe-area-context';
|
|
-import type {
|
|
- ParamListBase,
|
|
- Route,
|
|
- StackNavigationState,
|
|
-} from '@react-navigation/native';
|
|
+import type { NavigationState as StackNavigationState } from 'react-navigation';
|
|
|
|
import {
|
|
MaybeScreenContainer,
|
|
@@ -32,6 +28,7 @@
|
|
Layout,
|
|
StackHeaderMode,
|
|
StackCardMode,
|
|
+ Route,
|
|
Scene,
|
|
StackDescriptorMap,
|
|
StackNavigationOptions,
|
|
@@ -45,7 +42,7 @@
|
|
type Props = {
|
|
mode: StackCardMode;
|
|
insets: EdgeInsets;
|
|
- state: StackNavigationState<ParamListBase>;
|
|
+ state: StackNavigationState;
|
|
descriptors: StackDescriptorMap;
|
|
routes: Route<string>[];
|
|
openingRouteKeys: string[];
|
|
diff -Naur ../../node_modules/@react-navigation/stack/src/views/Stack/StackView.tsx src/vendor/views/Stack/StackView.tsx
|
|
--- ../../node_modules/@react-navigation/stack/src/views/Stack/StackView.tsx 2020-10-26 16:07:00.000000000 +0100
|
|
+++ src/vendor/views/Stack/StackView.tsx 2020-10-26 16:20:15.000000000 +0100
|
|
@@ -2,12 +2,11 @@
|
|
import { View, Platform, StyleSheet } from 'react-native';
|
|
import { SafeAreaConsumer, EdgeInsets } from 'react-native-safe-area-context';
|
|
import {
|
|
- NavigationHelpersContext,
|
|
StackActions,
|
|
- StackNavigationState,
|
|
- Route,
|
|
- ParamListBase,
|
|
-} from '@react-navigation/native';
|
|
+ NavigationState as StackNavigationState,
|
|
+ NavigationActions,
|
|
+ SceneView,
|
|
+} from 'react-navigation';
|
|
|
|
import { GestureHandlerRootView } from '../GestureHandler';
|
|
import CardStack from './CardStack';
|
|
@@ -17,6 +16,7 @@
|
|
} from '../Header/HeaderContainer';
|
|
import SafeAreaProviderCompat from '../SafeAreaProviderCompat';
|
|
import type {
|
|
+ Route,
|
|
StackNavigationHelpers,
|
|
StackNavigationConfig,
|
|
StackDescriptorMap,
|
|
@@ -24,9 +24,10 @@
|
|
import HeaderShownContext from '../../utils/HeaderShownContext';
|
|
|
|
type Props = StackNavigationConfig & {
|
|
- state: StackNavigationState<ParamListBase>;
|
|
+ state: StackNavigationState;
|
|
navigation: StackNavigationHelpers;
|
|
descriptors: StackDescriptorMap;
|
|
+ screenProps: unknown;
|
|
};
|
|
|
|
type State = {
|
|
@@ -295,7 +296,9 @@
|
|
return false;
|
|
}
|
|
|
|
- return gestureEnabled !== false;
|
|
+ return gestureEnabled !== undefined
|
|
+ ? gestureEnabled
|
|
+ : Platform.OS !== 'android';
|
|
}
|
|
|
|
return false;
|
|
@@ -323,26 +326,49 @@
|
|
return null;
|
|
}
|
|
|
|
- return descriptor.render();
|
|
+ const { navigation, getComponent } = descriptor;
|
|
+ const SceneComponent = getComponent();
|
|
+
|
|
+ return (
|
|
+ <SceneView
|
|
+ screenProps={this.props.screenProps}
|
|
+ navigation={navigation}
|
|
+ component={SceneComponent}
|
|
+ />
|
|
+ );
|
|
};
|
|
|
|
private renderHeader = (props: HeaderContainerProps) => {
|
|
return <HeaderContainer {...props} />;
|
|
};
|
|
|
|
+ private handleTransitionComplete = () => {
|
|
+ const { state, navigation } = this.props;
|
|
+
|
|
+ if (state.isTransitioning) {
|
|
+ navigation.dispatch(
|
|
+ StackActions.completeTransition({
|
|
+ key: navigation.state.key,
|
|
+ toChildKey: state.routes[state.index].key,
|
|
+ })
|
|
+ );
|
|
+ }
|
|
+ };
|
|
+
|
|
private handleOpenRoute = ({ route }: { route: Route<string> }) => {
|
|
const { state, navigation } = this.props;
|
|
const { closingRouteKeys, replacingRouteKeys } = this.state;
|
|
|
|
+ this.handleTransitionComplete();
|
|
+
|
|
if (
|
|
closingRouteKeys.some((key) => key === route.key) &&
|
|
replacingRouteKeys.every((key) => key !== route.key) &&
|
|
- state.routeNames.includes(route.name) &&
|
|
!state.routes.some((r) => r.key === route.key)
|
|
) {
|
|
// If route isn't present in current state, but was closing, assume that a close animation was cancelled
|
|
// So we need to add this route back to the state
|
|
- navigation.navigate(route);
|
|
+ navigation.dispatch(NavigationActions.navigate(route));
|
|
} else {
|
|
this.setState((state) => ({
|
|
routes: state.replacingRouteKeys.length
|
|
@@ -368,12 +394,11 @@
|
|
// If a route exists in state, trigger a pop
|
|
// This will happen in when the route was closed from the card component
|
|
// e.g. When the close animation triggered from a gesture ends
|
|
- navigation.dispatch({
|
|
- ...StackActions.pop(),
|
|
- source: route.key,
|
|
- target: state.key,
|
|
- });
|
|
+ // @ts-ignore
|
|
+ navigation.dispatch(StackActions.pop({ key: route.key, prune: false }));
|
|
} else {
|
|
+ this.handleTransitionComplete();
|
|
+
|
|
// 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),
|
|
@@ -390,47 +415,41 @@
|
|
private handleTransitionStart = (
|
|
{ route }: { route: Route<string> },
|
|
closing: boolean
|
|
- ) =>
|
|
- this.props.navigation.emit({
|
|
- type: 'transitionStart',
|
|
- data: { closing },
|
|
- target: route.key,
|
|
- });
|
|
+ ) => {
|
|
+ const { descriptors } = this.props;
|
|
+ const descriptor =
|
|
+ descriptors[route.key] || this.state.descriptors[route.key];
|
|
+
|
|
+ descriptor?.options.onTransitionStart?.({ closing });
|
|
+ };
|
|
|
|
private handleTransitionEnd = (
|
|
{ route }: { route: Route<string> },
|
|
closing: boolean
|
|
- ) =>
|
|
- this.props.navigation.emit({
|
|
- type: 'transitionEnd',
|
|
- data: { closing },
|
|
- target: route.key,
|
|
- });
|
|
-
|
|
- private handleGestureStart = ({ route }: { route: Route<string> }) => {
|
|
- this.props.navigation.emit({
|
|
- type: 'gestureStart',
|
|
- target: route.key,
|
|
- });
|
|
- };
|
|
-
|
|
- private handleGestureEnd = ({ route }: { route: Route<string> }) => {
|
|
- this.props.navigation.emit({
|
|
- type: 'gestureEnd',
|
|
- target: route.key,
|
|
- });
|
|
- };
|
|
-
|
|
- private handleGestureCancel = ({ route }: { route: Route<string> }) => {
|
|
- this.props.navigation.emit({
|
|
- type: 'gestureCancel',
|
|
- target: route.key,
|
|
- });
|
|
+ ) => {
|
|
+ const { descriptors } = this.props;
|
|
+ const descriptor =
|
|
+ descriptors[route.key] || this.state.descriptors[route.key];
|
|
+
|
|
+ descriptor?.options.onTransitionStart?.({ closing });
|
|
+ };
|
|
+
|
|
+ private handleGestureStart = () => {
|
|
+ // Do nothing
|
|
+ };
|
|
+
|
|
+ private handleGestureEnd = () => {
|
|
+ // Do nothing
|
|
+ };
|
|
+
|
|
+ private handleGestureCancel = () => {
|
|
+ // Do nothing
|
|
};
|
|
|
|
render() {
|
|
const {
|
|
state,
|
|
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
navigation,
|
|
keyboardHandlingEnabled,
|
|
mode = 'card',
|
|
@@ -450,7 +469,7 @@
|
|
} = this.state;
|
|
|
|
return (
|
|
- <NavigationHelpersContext.Provider value={navigation}>
|
|
+ <>
|
|
<GestureHandlerWrapper style={styles.container}>
|
|
<SafeAreaProviderCompat>
|
|
<SafeAreaConsumer>
|
|
@@ -491,7 +510,7 @@
|
|
</SafeAreaConsumer>
|
|
</SafeAreaProviderCompat>
|
|
</GestureHandlerWrapper>
|
|
- </NavigationHelpersContext.Provider>
|
|
+ </>
|
|
);
|
|
}
|
|
}
|