Skip to content

Commit

Permalink
Merge pull request #31723 from lukemorawski/31677-theme_switching_nav…
Browse files Browse the repository at this point in the history
…igation_signin_wholeapp

[Theme Switching Migration] Navigation + SignIn + WholeApp Batch
  • Loading branch information
grgia authored Nov 29, 2023
2 parents 0a49854 + e93fb3d commit dca1716
Show file tree
Hide file tree
Showing 14 changed files with 91 additions and 66 deletions.
36 changes: 19 additions & 17 deletions src/components/GrowlNotification/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,11 @@ import * as Pressables from '@components/Pressable';
import Text from '@components/Text';
import * as Growl from '@libs/Growl';
import useNativeDriver from '@libs/useNativeDriver';
import styles from '@styles/styles';
import themeColors from '@styles/themes/default';
import useTheme from '@styles/themes/useTheme';
import useThemeStyles from '@styles/useThemeStyles';
import CONST from '@src/CONST';
import GrowlNotificationContainer from './GrowlNotificationContainer';

const types = {
[CONST.GROWL.SUCCESS]: {
icon: Expensicons.Checkmark,
iconColor: themeColors.success,
},
[CONST.GROWL.ERROR]: {
icon: Expensicons.Exclamation,
iconColor: themeColors.danger,
},
[CONST.GROWL.WARNING]: {
icon: Expensicons.Exclamation,
iconColor: themeColors.warning,
},
};

const INACTIVE_POSITION_Y = -255;

const PressableWithoutFeedback = Pressables.PressableWithoutFeedback;
Expand All @@ -36,6 +21,23 @@ function GrowlNotification(_, ref) {
const [bodyText, setBodyText] = useState('');
const [type, setType] = useState('success');
const [duration, setDuration] = useState();
const styles = useThemeStyles();
const theme = useTheme();

const types = {
[CONST.GROWL.SUCCESS]: {
icon: Expensicons.Checkmark,
iconColor: theme.success,
},
[CONST.GROWL.ERROR]: {
icon: Expensicons.Exclamation,
iconColor: theme.danger,
},
[CONST.GROWL.WARNING]: {
icon: Expensicons.Exclamation,
iconColor: theme.warning,
},
};

/**
* Show the growl notification
Expand Down
7 changes: 4 additions & 3 deletions src/components/ScreenWrapper/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import useKeyboardState from '@hooks/useKeyboardState';
import useNetwork from '@hooks/useNetwork';
import useWindowDimensions from '@hooks/useWindowDimensions';
import * as Browser from '@libs/Browser';
import styles from '@styles/styles';
import useThemeStyles from '@styles/useThemeStyles';
import toggleTestToolsModal from '@userActions/TestTool';
import CONST from '@src/CONST';
import {defaultProps, propTypes} from './propTypes';
Expand Down Expand Up @@ -44,6 +44,7 @@ const ScreenWrapper = React.forwardRef(
) => {
const {windowHeight, isSmallScreenWidth} = useWindowDimensions();
const {initialHeight} = useInitialDimensions();
const styles = useThemeStyles();
const keyboardState = useKeyboardState();
const {isDevelopment} = useEnvironment();
const {isOffline} = useNetwork();
Expand All @@ -59,14 +60,14 @@ const ScreenWrapper = React.forwardRef(

const panResponder = useRef(
PanResponder.create({
onStartShouldSetPanResponderCapture: (e, gestureState) => gestureState.numberActiveTouches === CONST.TEST_TOOL.NUMBER_OF_TAPS,
onStartShouldSetPanResponderCapture: (_e, gestureState) => gestureState.numberActiveTouches === CONST.TEST_TOOL.NUMBER_OF_TAPS,
onPanResponderRelease: toggleTestToolsModal,
}),
).current;

const keyboardDissmissPanResponder = useRef(
PanResponder.create({
onMoveShouldSetPanResponderCapture: (e, gestureState) => {
onMoveShouldSetPanResponderCapture: (_e, gestureState) => {
const isHorizontalSwipe = Math.abs(gestureState.dx) > Math.abs(gestureState.dy);
const shouldDismissKeyboard = shouldDismissKeyboardBeforeClose && isKeyboardShown && Browser.isMobile();

Expand Down
2 changes: 1 addition & 1 deletion src/libs/Navigation/AppNavigator/AuthScreens.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ const defaultProps = {
function AuthScreens({isUsingMemoryOnlyKeys, lastUpdateIDAppliedToClient, session, lastOpenedPublicRoomID, demoInfo}) {
const styles = useThemeStyles();
const {isSmallScreenWidth} = useWindowDimensions();
const screenOptions = getRootNavigatorScreenOptions(isSmallScreenWidth);
const screenOptions = getRootNavigatorScreenOptions(isSmallScreenWidth, styles);
const isInitialRender = useRef(true);

if (isInitialRender.current) {
Expand Down
21 changes: 13 additions & 8 deletions src/libs/Navigation/AppNavigator/ModalStackNavigators.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
import {CardStyleInterpolators, createStackNavigator} from '@react-navigation/stack';
import React from 'react';
import React, {useMemo} from 'react';
import _ from 'underscore';
import styles from '@styles/styles';
import useThemeStyles from '@styles/useThemeStyles';
import SCREENS from '@src/SCREENS';

const defaultSubRouteOptions = {
cardStyle: styles.navigationScreenCardStyle,
headerShown: false,
cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS,
};

/**
* Create a modal stack navigator with an array of sub-screens.
*
Expand All @@ -20,6 +14,17 @@ function createModalStackNavigator(screens) {
const ModalStackNavigator = createStackNavigator();

function ModalStack() {
const styles = useThemeStyles();

const defaultSubRouteOptions = useMemo(
() => ({
cardStyle: styles.navigationScreenCardStyle,
headerShown: false,
cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS,
}),
[styles],
);

return (
<ModalStackNavigator.Navigator screenOptions={defaultSubRouteOptions}>
{_.map(screens, (getComponent, name) => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {createStackNavigator} from '@react-navigation/stack';
import React from 'react';
import ReportScreenWrapper from '@libs/Navigation/AppNavigator/ReportScreenWrapper';
import getCurrentUrl from '@libs/Navigation/currentUrl';
import styles from '@styles/styles';
import useThemeStyles from '@styles/useThemeStyles';
import SCREENS from '@src/SCREENS';

const Stack = createStackNavigator();
Expand All @@ -11,6 +11,7 @@ const url = getCurrentUrl();
const openOnAdminRoom = url ? new URL(url).searchParams.get('openOnAdminRoom') : undefined;

function BaseCentralPaneNavigator() {
const styles = useThemeStyles();
return (
<Stack.Navigator>
<Stack.Screen
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {createStackNavigator} from '@react-navigation/stack';
import PropTypes from 'prop-types';
import React from 'react';
import React, {useMemo} from 'react';
import {View} from 'react-native';
import NoDropZone from '@components/DragAndDrop/NoDropZone';
import useWindowDimensions from '@hooks/useWindowDimensions';
Expand All @@ -21,12 +21,13 @@ const propTypes = {
function RightModalNavigator(props) {
const styles = useThemeStyles();
const {isSmallScreenWidth} = useWindowDimensions();
const screenOptions = useMemo(() => RHPScreenOptions(styles), [styles]);

return (
<NoDropZone>
{!isSmallScreenWidth && <Overlay onPress={props.navigation.goBack} />}
<View style={styles.RHPNavigatorContainer(isSmallScreenWidth)}>
<Stack.Navigator screenOptions={RHPScreenOptions}>
<Stack.Navigator screenOptions={screenOptions}>
<Stack.Screen
name="Settings"
component={ModalStackNavigators.SettingsModalStackNavigator}
Expand Down
11 changes: 8 additions & 3 deletions src/libs/Navigation/AppNavigator/RHPScreenOptions.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import {CardStyleInterpolators} from '@react-navigation/stack';
import styles from '@styles/styles';

const RHPScreenOptions = {
/**
* RHP stack navigator screen options generator function
* @function
* @param {Object} styles - The styles object
* @returns {Object} - The screen options object
*/
const RHPScreenOptions = (styles) => ({
headerShown: false,
animationEnabled: true,
gestureDirection: 'horizontal',
cardStyle: styles.navigationScreenCardStyle,
cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS,
};
});

export default RHPScreenOptions;
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import getNavigationModalCardStyle from '@styles/getNavigationModalCardStyles';
import styles from '@styles/styles';
import variables from '@styles/variables';
import CONFIG from '@src/CONFIG';
import modalCardStyleInterpolator from './modalCardStyleInterpolator';
Expand All @@ -12,7 +11,7 @@ const commonScreenOptions = {
animationTypeForReplace: 'push',
};

export default (isSmallScreenWidth) => ({
export default (isSmallScreenWidth, styles) => ({
rightModalNavigator: {
...commonScreenOptions,
cardStyleInterpolator: (props) => modalCardStyleInterpolator(isSmallScreenWidth, false, props),
Expand Down
34 changes: 19 additions & 15 deletions src/libs/Navigation/NavigationRoot.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,17 @@
import {DefaultTheme, getPathFromState, NavigationContainer, NavigationState} from '@react-navigation/native';
import React, {useEffect, useRef} from 'react';
import React, {useEffect, useMemo, useRef} from 'react';
import {ColorValue} from 'react-native';
import {interpolateColor, runOnJS, useAnimatedReaction, useSharedValue, withDelay, withTiming} from 'react-native-reanimated';
import useCurrentReportID from '@hooks/useCurrentReportID';
import useFlipper from '@hooks/useFlipper';
import useWindowDimensions from '@hooks/useWindowDimensions';
import Log from '@libs/Log';
import StatusBar from '@libs/StatusBar';
import themeColors from '@styles/themes/default';
import useTheme from '@styles/themes/useTheme';
import AppNavigator from './AppNavigator';
import linkingConfig from './linkingConfig';
import Navigation, {navigationRef} from './Navigation';

// https://reactnavigation.org/docs/themes
const navigationTheme = {
...DefaultTheme,
colors: {
...DefaultTheme.colors,
background: themeColors.appBG,
},
};

type NavigationRootProps = {
/** Whether the current user is logged in with an authToken */
authenticated: boolean;
Expand Down Expand Up @@ -51,11 +42,24 @@ function parseAndLogRoute(state: NavigationState) {

function NavigationRoot({authenticated, onReady}: NavigationRootProps) {
useFlipper(navigationRef);
const theme = useTheme();
const firstRenderRef = useRef(true);

const currentReportIDValue = useCurrentReportID();
const {isSmallScreenWidth} = useWindowDimensions();

// https://reactnavigation.org/docs/themes
const navigationTheme = useMemo(
() => ({
...DefaultTheme,
colors: {
...DefaultTheme.colors,
background: theme.appBG,
},
}),
[theme],
);

useEffect(() => {
if (firstRenderRef.current) {
// we don't want to make the report back button go back to LHN if the user
Expand All @@ -78,8 +82,8 @@ function NavigationRoot({authenticated, onReady}: NavigationRootProps) {
navigationRef.resetRoot(navigationRef.getRootState());
}, [isSmallScreenWidth, authenticated]);

const prevStatusBarBackgroundColor = useRef(themeColors.appBG);
const statusBarBackgroundColor = useRef(themeColors.appBG);
const prevStatusBarBackgroundColor = useRef(theme.appBG);
const statusBarBackgroundColor = useRef(theme.appBG);
const statusBarAnimation = useSharedValue(0);

const updateStatusBarBackgroundColor = (color: ColorValue) => StatusBar.setBackgroundColor(color);
Expand All @@ -101,7 +105,7 @@ function NavigationRoot({authenticated, onReady}: NavigationRootProps) {

const backgroundColorFromRoute =
currentRoute?.params && 'backgroundColor' in currentRoute.params && typeof currentRoute.params.backgroundColor === 'string' && currentRoute.params.backgroundColor;
const backgroundColorFallback = themeColors.PAGE_BACKGROUND_COLORS[currentRoute?.name as keyof typeof themeColors.PAGE_BACKGROUND_COLORS] || themeColors.appBG;
const backgroundColorFallback = currentRoute?.name ? theme.PAGE_BACKGROUND_COLORS[currentRoute.name] || theme.appBG : theme.appBG;

// It's possible for backgroundColorFromRoute to be empty string, so we must use "||" to fallback to backgroundColorFallback.
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
Expand All @@ -110,7 +114,7 @@ function NavigationRoot({authenticated, onReady}: NavigationRootProps) {
prevStatusBarBackgroundColor.current = statusBarBackgroundColor.current;
statusBarBackgroundColor.current = currentScreenBackgroundColor;

if (currentScreenBackgroundColor === themeColors.appBG && prevStatusBarBackgroundColor.current === themeColors.appBG) {
if (currentScreenBackgroundColor === theme.appBG && prevStatusBarBackgroundColor.current === theme.appBG) {
return;
}

Expand Down
6 changes: 4 additions & 2 deletions src/pages/signin/SignInPageLayout/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import PropTypes from 'prop-types';
import React, {forwardRef, useEffect, useImperativeHandle, useRef} from 'react';
import React, {forwardRef, useEffect, useImperativeHandle, useMemo, useRef} from 'react';
import {ScrollView, View} from 'react-native';
import {withSafeAreaInsets} from 'react-native-safe-area-context';
import SignInGradient from '@assets/images/home-fade-gradient.svg';
Expand Down Expand Up @@ -93,6 +93,8 @@ function SignInPageLayout(props) {
scrollPageToTop();
}, [props.welcomeHeader, props.welcomeText, prevPreferredLocale, props.preferredLocale]);

const scrollViewStyles = useMemo(() => scrollViewContentContainerStyles(styles), [styles]);

return (
<View style={containerStyles}>
{!props.shouldShowSmallScreen ? (
Expand Down Expand Up @@ -152,7 +154,7 @@ function SignInPageLayout(props) {
</View>
) : (
<ScrollView
contentContainerStyle={scrollViewContentContainerStyles}
contentContainerStyle={scrollViewStyles}
keyboardShouldPersistTaps="handled"
ref={scrollViewRef}
>
Expand Down
4 changes: 1 addition & 3 deletions src/pages/signin/SignInPageLayout/signInPageStyles/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import styles from '@styles/styles';

// On web, we can use flex to fit the content to fit the viewport within a ScrollView.
const scrollViewContentContainerStyles = styles.flex1;
const scrollViewContentContainerStyles = (styles) => styles.flex1;

export default scrollViewContentContainerStyles;
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import styles from '@styles/styles';

// Using flexGrow on mobile allows the ScrollView container to grow to fit the content.
// This is necessary because making the sign-in content fit exactly the viewheight causes the scroll to stop working on mobile.
const scrollViewContentContainerStyles = styles.flexGrow1;
const scrollViewContentContainerStyles = (styles) => styles.flexGrow1;

export default scrollViewContentContainerStyles;
17 changes: 12 additions & 5 deletions src/pages/signin/Terms.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
import React from 'react';
import React, {useMemo} from 'react';
import Text from '@components/Text';
import TextLink from '@components/TextLink';
import withLocalize, {withLocalizePropTypes} from '@components/withLocalize';
import styles from '@styles/styles';
import useThemeStyles from '@styles/useThemeStyles';
import CONST from '@src/CONST';

const linkStyles = [styles.textExtraSmallSupporting, styles.link];

function Terms(props) {
const styles = useThemeStyles();
const [linkStyles, containerStyles] = useMemo(
() => [
[styles.textExtraSmallSupporting, styles.link],
[styles.textExtraSmallSupporting, styles.mb4],
],
[styles],
);

return (
<Text style={[styles.textExtraSmallSupporting, styles.mb4]}>
<Text style={containerStyles}>
{props.translate('termsOfUse.phrase1')}
<TextLink
style={linkStyles}
Expand Down
4 changes: 3 additions & 1 deletion src/styles/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3984,5 +3984,7 @@ const styles = (theme: ThemeColors) =>
const stylesGenerator = styles;
const defaultStyles = styles(defaultTheme);

type ThemeStyle = typeof defaultStyles;

export default defaultStyles;
export {stylesGenerator, type Styles};
export {stylesGenerator, type Styles, type ThemeStyle};

0 comments on commit dca1716

Please sign in to comment.