refactor: consolidate modal checks

This commit is contained in:
Satyajit Sahoo
2021-08-07 14:29:58 +02:00
parent 99735e1b73
commit 0f5868f64d
3 changed files with 34 additions and 22 deletions

View File

@@ -12,7 +12,6 @@ import {
} from 'react-native';
import type { EdgeInsets } from 'react-native-safe-area-context';
import { forModalPresentationIOS } from '../../TransitionConfigs/CardStyleInterpolators';
import type {
GestureDirection,
Layout,
@@ -33,8 +32,8 @@ import ModalStatusBarManager from '../ModalStatusBarManager';
import CardSheet from './CardSheet';
type Props = ViewProps & {
// index: number;
interpolationIndex: number;
modal: boolean;
closing: boolean;
next?: Animated.AnimatedInterpolation;
current: Animated.AnimatedInterpolation;
@@ -430,8 +429,8 @@ export default class Card extends React.Component<Props> {
render() {
const {
styleInterpolator,
// index,
interpolationIndex,
modal,
current,
gesture,
next,
@@ -495,11 +494,7 @@ export default class Card extends React.Component<Props> {
{
// StatusBar messes with translucent status bar on Android
// So we should only enable it on iOS
Platform.OS === 'ios' &&
overlayEnabled &&
interpolationIndex === 0 &&
next &&
styleInterpolator === forModalPresentationIOS ? (
Platform.OS === 'ios' && modal && overlayEnabled && next ? (
<ModalStatusBarManager
dark={headerDarkContent}
layout={layout}

View File

@@ -8,7 +8,6 @@ import { Route, useTheme } from '@react-navigation/native';
import * as React from 'react';
import { Animated, StyleSheet, View } from 'react-native';
import { forModalPresentationIOS } from '../../TransitionConfigs/CardStyleInterpolators';
import type { Layout, Scene } from '../../types';
import ModalPresentationContext from '../../utils/ModalPresentationContext';
import useKeyboardManager from '../../utils/useKeyboardManager';
@@ -16,11 +15,12 @@ import type { Props as HeaderContainerProps } from '../Header/HeaderContainer';
import Card from './Card';
type Props = {
index: number;
interpolationIndex: number;
index: number;
active: boolean;
focused: boolean;
closing: boolean;
modal: boolean;
layout: Layout;
gesture: Animated.Value;
scene: Scene;
@@ -57,11 +57,13 @@ type Props = {
const EPSILON = 0.1;
function CardContainer({
interpolationIndex,
index,
active,
closing,
gesture,
focused,
modal,
getPreviousScene,
getFocusedRoute,
headerDarkContent,
@@ -71,7 +73,6 @@ function CardContainer({
isParentHeaderShown,
isNextScreenTransparent,
detachCurrentScreen,
interpolationIndex,
layout,
onCloseRoute,
onOpenRoute,
@@ -198,7 +199,6 @@ function CardContainer({
transitionSpec,
} = scene.descriptor.options;
const isModalPresentation = cardStyleInterpolator === forModalPresentationIOS;
const previousScene = getPreviousScene({ route: scene.descriptor.route });
let backTitle: string | undefined;
@@ -216,6 +216,7 @@ function CardContainer({
return (
<Card
modal={modal}
interpolationIndex={interpolationIndex}
gestureDirection={gestureDirection}
layout={layout}
@@ -290,9 +291,7 @@ function CardContainer({
</HeaderBackContext.Provider>
</View>
{headerMode !== 'float' ? (
<ModalPresentationContext.Provider
value={isModalPresentation && interpolationIndex !== 0}
>
<ModalPresentationContext.Provider value={modal}>
{renderHeader({
mode: 'screen',
layout,

View File

@@ -30,6 +30,7 @@ import {
import type {
Layout,
Scene,
StackCardStyleInterpolator,
StackDescriptor,
StackDescriptorMap,
StackHeaderMode,
@@ -107,6 +108,24 @@ const getInterpolationIndex = (scenes: Scene[], index: number) => {
return interpolationIndex;
};
const getIsModalPresentation = (
cardStyleInterpolator: StackCardStyleInterpolator
) => {
return (
cardStyleInterpolator === forModalPresentationIOS ||
// Handle custom modal presentation interpolators as well
cardStyleInterpolator.name === 'forModalPresentationIOS'
);
};
const getIsModal = (scene: Scene, interpolationIndex: number) => {
const { cardStyleInterpolator } = scene.descriptor.options;
const isModalPresentation = getIsModalPresentation(cardStyleInterpolator);
const isModal = isModalPresentation && interpolationIndex !== 0;
return isModal;
};
const getHeaderHeights = (
scenes: Scene[],
insets: EdgeInsets,
@@ -117,7 +136,6 @@ const getHeaderHeights = (
return scenes.reduce<Record<string, number>>((acc, curr, index) => {
const {
headerStatusBarHeight = isParentHeaderShown ? 0 : insets.top,
cardStyleInterpolator,
headerStyle,
} = curr.descriptor.options;
@@ -129,9 +147,7 @@ const getHeaderHeights = (
: previous[curr.route.key];
const interpolationIndex = getInterpolationIndex(scenes, index);
const isModalPresentation =
cardStyleInterpolator === forModalPresentationIOS;
const isModal = isModalPresentation && interpolationIndex !== 0;
const isModal = getIsModal(curr, interpolationIndex);
acc[curr.route.key] =
typeof height === 'number'
@@ -269,7 +285,7 @@ export default class CardStack extends React.Component<Props, State> {
headerStyleInterpolator = defaultTransitionPreset.headerStyleInterpolator,
cardOverlayEnabled = (Platform.OS !== 'ios' &&
optionsForTransitionConfig.presentation !== 'transparentModal') ||
cardStyleInterpolator === forModalPresentationIOS,
getIsModalPresentation(cardStyleInterpolator),
} = optionsForTransitionConfig;
const headerMode: StackHeaderMode =
@@ -279,7 +295,7 @@ export default class CardStack extends React.Component<Props, State> {
optionsForTransitionConfig.presentation === 'transparentModal' ||
nextDescriptor?.options.presentation === 'modal' ||
nextDescriptor?.options.presentation === 'transparentModal' ||
cardStyleInterpolator === forModalPresentationIOS
getIsModalPresentation(cardStyleInterpolator)
) &&
Platform.OS === 'ios' &&
descriptor.options.header === undefined
@@ -500,7 +516,7 @@ export default class CardStack extends React.Component<Props, State> {
// By default, we don't want to detach the previous screen of the active one for modals
detachPreviousScreen = options.presentation === 'transparentModal'
? false
: options.cardStyleInterpolator === forModalPresentationIOS
: getIsModalPresentation(options.cardStyleInterpolator)
? i !==
scenes
.map((scene) => scene.descriptor.options.cardStyleInterpolator)
@@ -605,6 +621,7 @@ export default class CardStack extends React.Component<Props, State> {
// Start from current card and count backwards the number of cards with same interpolation
const interpolationIndex = getInterpolationIndex(scenes, index);
const isModal = getIsModal(scene, interpolationIndex);
const isNextScreenTransparent =
scenes[index + 1]?.descriptor.options.presentation ===
@@ -625,6 +642,7 @@ export default class CardStack extends React.Component<Props, State> {
<CardContainer
index={index}
interpolationIndex={interpolationIndex}
modal={isModal}
active={index === self.length - 1}
focused={focused}
closing={closingRouteKeys.includes(route.key)}