refactor: enable screens only for last screen

This will avoid issues such as https://github.com/react-navigation/react-navigation/issues/6909
This commit is contained in:
Satyajit Sahoo
2020-02-22 19:39:50 +01:00
parent 85e9376302
commit c19da31240
2 changed files with 18 additions and 76 deletions

View File

@@ -7,7 +7,11 @@ import {
StatusBar,
I18nManager,
} from 'react-native';
// eslint-disable-next-line import/no-unresolved
import { enableScreens } from 'react-native-screens';
import RNRestart from 'react-native-restart';
import { Updates } from 'expo';
import { Asset } from 'expo-asset';
import { MaterialIcons } from '@expo/vector-icons';
import {
Provider as PaperProvider,
@@ -17,7 +21,6 @@ import {
List,
Divider,
} from 'react-native-paper';
import { Asset } from 'expo-asset';
import {
InitialState,
useLinking,
@@ -49,10 +52,11 @@ import DynamicTabs from './Screens/DynamicTabs';
import AuthFlow from './Screens/AuthFlow';
import CompatAPI from './Screens/CompatAPI';
import SettingsItem from './Shared/SettingsItem';
import { Updates } from 'expo';
YellowBox.ignoreWarnings(['Require cycle:', 'Warning: Async Storage']);
enableScreens();
type RootDrawerParamList = {
Root: undefined;
Another: undefined;

View File

@@ -37,14 +37,6 @@ type GestureValues = {
[key: string]: Animated.Value;
};
// @ts-ignore
const maybeExpoVersion = global.Expo?.Constants.manifest.sdkVersion.split(
'.'
)[0];
const isInsufficientExpoVersion = maybeExpoVersion
? Number(maybeExpoVersion) <= 36
: maybeExpoVersion === 'UNVERSIONED';
type Props = {
mode: StackCardMode;
insets: EdgeInsets;
@@ -82,37 +74,27 @@ type State = {
};
const EPSILON = 0.01;
const FAR_FAR_AWAY = 9000;
const dimensions = Dimensions.get('window');
const layout = { width: dimensions.width, height: dimensions.height };
const MaybeScreenContainer = ({
enabled,
style,
...rest
}: ViewProps & {
enabled: boolean;
children: React.ReactNode;
}) => {
if (enabled && screensEnabled()) {
return <ScreenContainer style={style} {...rest} />;
return <ScreenContainer {...rest} />;
}
return (
<View
collapsable={!enabled}
removeClippedSubviews={Platform.OS !== 'ios' && enabled}
style={[style, { overflow: 'hidden' }]}
{...rest}
/>
);
return <View {...rest} />;
};
const MaybeScreen = ({
enabled,
active,
style,
...rest
}: ViewProps & {
enabled: boolean;
@@ -121,39 +103,10 @@ const MaybeScreen = ({
}) => {
if (enabled && screensEnabled()) {
// @ts-ignore
return <Screen active={active} style={style} {...rest} />;
return <Screen active={active} {...rest} />;
}
return (
<Animated.View
style={[
style,
{
overflow: 'hidden',
// Position the screen offscreen to take advantage of offscreen perf optimization
// https://facebook.github.io/react-native/docs/view#removeclippedsubviews
// This can be useful if screens is not enabled
// It's buggy on iOS, so we don't enable it there
top:
enabled && typeof active === 'number' && !active ? FAR_FAR_AWAY : 0,
transform: [
{
// If the `active` prop is animated node, we can't use the `left` property due to native driver
// So we use `translateY` instead
translateY:
enabled && typeof active !== 'number'
? active.interpolate({
inputRange: [0, 1],
outputRange: [FAR_FAR_AWAY, 0],
})
: 0,
},
],
},
]}
{...rest}
/>
);
return <View {...rest} />;
};
const FALLBACK_DESCRIPTOR = Object.freeze({ options: {} });
@@ -450,9 +403,7 @@ export default class CardStack extends React.Component<Props, State> {
// Screens is buggy on iOS, so we don't enable it there
// For modals, usually we want the screen underneath to be visible, so also disable it there
const isScreensEnabled =
Platform.OS !== 'ios' &&
(isInsufficientExpoVersion ? mode !== 'modal' : true);
const isScreensEnabled = Platform.OS !== 'ios' && mode !== 'modal';
return (
<React.Fragment>
@@ -466,26 +417,13 @@ export default class CardStack extends React.Component<Props, State> {
const gesture = gestures[route.key];
const scene = scenes[index];
// Display current screen and a screen beneath.
let isScreenActive: Animated.AnimatedInterpolation | 0 | 1 =
index >= self.length - 2 ? 1 : 0;
if (isInsufficientExpoVersion) {
isScreenActive =
index === self.length - 1
? 1
: Platform.OS === 'android'
? scene.progress.next
? scene.progress.next.interpolate({
inputRange: [0, 1 - EPSILON, 1],
outputRange: [1, 1, 0],
extrapolate: 'clamp',
})
: 1
: index === self.length - 2
? 1
: 0;
}
const isScreenActive = scene.progress.next
? scene.progress.next.interpolate({
inputRange: [0, 1 - EPSILON, 1],
outputRange: [1, 1, 0],
extrapolate: 'clamp',
})
: 1;
const {
safeAreaInsets,