Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SignInPage always dark mode #31636

Merged
merged 16 commits into from
Nov 27, 2023
Merged
30 changes: 22 additions & 8 deletions src/pages/signin/SignInPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import Log from '@libs/Log';
import Navigation from '@libs/Navigation/Navigation';
import Performance from '@libs/Performance';
import * as StyleUtils from '@styles/StyleUtils';
import ThemeProvider from '@styles/themes/ThemeProvider';
import ThemeStylesProvider from '@styles/ThemeStylesProvider';
import useThemeStyles from '@styles/useThemeStyles';
import * as App from '@userActions/App';
import * as Session from '@userActions/Session';
Expand Down Expand Up @@ -135,7 +137,7 @@ function getRenderOptions({hasLogin, hasValidateCode, account, isPrimaryLogin, i
};
}

function SignInPage({credentials, account, isInModal, activeClients, preferredLocale}) {
function SignInPageInner({credentials, account, isInModal, activeClients, preferredLocale}) {
const styles = useThemeStyles();
const {translate, formatPhoneNumber} = useLocalize();
const {isSmallScreenWidth} = useWindowDimensions();
Expand Down Expand Up @@ -269,18 +271,30 @@ function SignInPage({credentials, account, isInModal, activeClients, preferredLo
</View>
);
}
SignInPageInner.propTypes = propTypes;
SignInPageInner.defaultProps = defaultProps;
SignInPageInner.displayName = 'SignInPage';

SignInPage.propTypes = propTypes;
SignInPage.defaultProps = defaultProps;
SignInPage.displayName = 'SignInPage';
function SignInPage(props) {
return (
<ThemeProvider theme={CONST.THEME.DARK}>
<ThemeStylesProvider>
<SignInPageInner
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
/>
</ThemeStylesProvider>
</ThemeProvider>
);
}

export default withOnyx({
account: {key: ONYXKEYS.ACCOUNT},
credentials: {key: ONYXKEYS.CREDENTIALS},
/**
This variable is only added to make sure the component is re-rendered
whenever the activeClients change, so that we call the
ActiveClientManager.isClientTheLeader function
/**
This variable is only added to make sure the component is re-rendered
whenever the activeClients change, so that we call the
ActiveClientManager.isClientTheLeader function
everytime the leader client changes.
We use that function to prevent repeating code that checks which client is the leader.
*/
Expand Down
4 changes: 1 addition & 3 deletions src/styles/ThemeStylesProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ import {stylesGenerator} from './styles';
import useTheme from './themes/useTheme';
import ThemeStylesContext from './ThemeStylesContext';

type ThemeStylesProviderProps = {
children: React.ReactNode;
};
type ThemeStylesProviderProps = React.PropsWithChildren;

function ThemeStylesProvider({children}: ThemeStylesProviderProps) {
const theme = useTheme();
Expand Down
19 changes: 11 additions & 8 deletions src/styles/themes/ThemeProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
/* eslint-disable react/jsx-props-no-spreading */
import PropTypes from 'prop-types';
import React, {useMemo} from 'react';
import CONST from '@src/CONST';
import darkTheme from './default';
import lightTheme from './light';
import ThemeContext from './ThemeContext';
import useThemePreference from './useThemePreference';
import Themes from './Themes';
import {ThemePreferenceWithoutSystem} from './types';
import useThemePreferenceWithStaticOverride from './useThemePreferenceWithStaticOverride';

const propTypes = {
/** Rendered child component */
children: PropTypes.node.isRequired,
};

function ThemeProvider(props: React.PropsWithChildren) {
const themePreference = useThemePreference();
type ThemeProviderProps = React.PropsWithChildren & {
theme?: ThemePreferenceWithoutSystem;
};

function ThemeProvider({children, theme: staticThemePreference}: ThemeProviderProps) {
const themePreference = useThemePreferenceWithStaticOverride(staticThemePreference);

const theme = useMemo(() => (themePreference === CONST.THEME.LIGHT ? lightTheme : darkTheme), [themePreference]);
const theme = useMemo(() => Themes[themePreference], [themePreference]);

return <ThemeContext.Provider value={theme}>{props.children}</ThemeContext.Provider>;
return <ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>;
}

ThemeProvider.propTypes = propTypes;
Expand Down
11 changes: 11 additions & 0 deletions src/styles/themes/Themes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import CONST from '@src/CONST';
import darkTheme from './default';
import lightTheme from './light';
import {ThemeColors, ThemePreferenceWithoutSystem} from './types';

const Themes = {
[CONST.THEME.LIGHT]: lightTheme,
[CONST.THEME.DARK]: darkTheme,
} satisfies Record<ThemePreferenceWithoutSystem, ThemeColors>;

export default Themes;
7 changes: 6 additions & 1 deletion src/styles/themes/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import CONST from '@src/CONST';

type Color = string;

type ThemePreference = (typeof CONST.THEME)[keyof typeof CONST.THEME];
type ThemePreferenceWithoutSystem = Exclude<ThemePreference, 'system'>;

type ThemeColors = {
// Figma keys
appBG: Color;
Expand Down Expand Up @@ -86,4 +91,4 @@ type ThemeColors = {
PAGE_BACKGROUND_COLORS: Record<string, Color>;
};

export {type ThemeColors, type Color};
export {type ThemePreference, type ThemePreferenceWithoutSystem, type ThemeColors, type Color};
5 changes: 2 additions & 3 deletions src/styles/themes/useThemePreference.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ import {useContext, useEffect, useState} from 'react';
import {Appearance, ColorSchemeName} from 'react-native';
import {PreferredThemeContext} from '@components/OnyxProvider';
import CONST from '@src/CONST';

type ThemePreference = typeof CONST.THEME.LIGHT | typeof CONST.THEME.DARK;
import {ThemePreferenceWithoutSystem} from './types';

function useThemePreference() {
const [themePreference, setThemePreference] = useState<ThemePreference>(CONST.THEME.DEFAULT);
const [themePreference, setThemePreference] = useState<ThemePreferenceWithoutSystem>(CONST.THEME.DEFAULT);
const [systemTheme, setSystemTheme] = useState<ColorSchemeName>();
const preferredThemeFromStorage = useContext(PreferredThemeContext);

Expand Down
14 changes: 14 additions & 0 deletions src/styles/themes/useThemePreferenceWithStaticOverride.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {ThemePreferenceWithoutSystem} from './types';
import useThemePreference from './useThemePreference';

const useThemePreferenceWithStaticOverride = (staticThemePreference: ThemePreferenceWithoutSystem | undefined) => {
const dynamicThemePreference = useThemePreference();

// If the "theme" prop is provided, we'll want to use a hardcoded/static theme instead of the currently selected dynamic theme
// This is used for example on the "SignInPage", because it should always display in dark mode.
const themePreference = staticThemePreference ?? dynamicThemePreference;

return themePreference;
};

export default useThemePreferenceWithStaticOverride;
Loading