Skip to content

Commit

Permalink
Merge pull request #31636 from margelo/@chrispader/dark-sign-in-page
Browse files Browse the repository at this point in the history
`SignInPage` always dark mode
  • Loading branch information
grgia authored Nov 27, 2023
2 parents 1950104 + 938bd28 commit 29b3ca1
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 23 deletions.
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;

0 comments on commit 29b3ca1

Please sign in to comment.