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

FIX#945 - Dark Mode Reverts to Light Mode After Refresh #948

Open
wants to merge 3 commits into
base: andrew_testing
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 39 additions & 21 deletions packages/app/context/theme.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,33 @@
import { createContext, useReducer } from 'react';
import { theme, darkTheme } from '../theme';
import { type PropsWithChildren, createContext, useReducer } from 'react';
import { getTheme } from '../theme';
import { ThemeEnum, type ThemeType } from '../theme/types';
import ThirdPartyThemeProviders from './ThirdPartyThemeProviders';
import React from 'react';
import { useStorage } from '../hooks/storage/useStorage';
import { useIsomorphicLayoutEffect } from 'tamagui';

const DEFAULT_THEME = ThemeEnum.LIGHT as ThemeType;

// Set default theme in initial state
const initialState = {
isDark: false,
isLight: true,
currentTheme: theme,
isDark: DEFAULT_THEME === ThemeEnum.DARK,
isLight: DEFAULT_THEME === ThemeEnum.LIGHT,
currentTheme: getTheme(DEFAULT_THEME),
};

/**
* Enables dark mode by updating the state object.
*
* @param {object} state - The current state object.
* @return {object} The updated state object with dark mode enabled.
*/

const handlers = {
/**
* Enables dark mode by updating the state object.
*
* @param {object} state - The current state object.
* @return {object} The updated state object with dark mode enabled.
*/
ENABLE_DARK_MODE: (state) => ({
...state,
isDark: true,
isLight: false,
currentTheme: darkTheme,
currentTheme: getTheme(ThemeEnum.DARK),
}),
/**
* Enables light mode by updating the state object.
Expand All @@ -31,13 +39,15 @@ const handlers = {
...state,
isDark: false,
isLight: true,
currentTheme: theme,
currentTheme: getTheme(ThemeEnum.LIGHT),
}),
};

const reducer = (state, action) => {
const handler = handlers[action.type];
return handler ? handler(state, action) : state;
};

const ThemeContext = createContext({
...initialState,
platform: 'JWT',
Expand All @@ -49,15 +59,21 @@ const ThemeContext = createContext({
},
});

/**
* Creates a ThemeProvider component that wraps the provided children with a context provider for managing the theme state.
*
* @param {Object} props - The properties object.
* @param {ReactNode} props.children - The children components to be wrapped.
* @return {ReactNode} - The wrapped children components.
*/
export const ThemeProvider = ({ children }) => {
export const ThemeProvider = ({ children }: PropsWithChildren) => {
const [state, dispatch] = useReducer(reducer, initialState);
const [[isThemeLoading, storedTheme], setStoredTheme] = useStorage('theme');

/**
* Initializes the app theme based on the stored theme preference.
* If no preference is stored, sets the default theme preference in local storage.
*/
useIsomorphicLayoutEffect(() => {
if (storedTheme) {
dispatch({ type: `ENABLE_${storedTheme}_MODE` });
} else {
setStoredTheme(DEFAULT_THEME);
}
}, [isThemeLoading]);

/**
* Enable dark mode.
Expand All @@ -66,6 +82,7 @@ export const ThemeProvider = ({ children }) => {
*/
const enableDarkMode = () => {
dispatch({ type: 'ENABLE_DARK_MODE' });
setStoredTheme(ThemeEnum.DARK);
};
/**
* Enables light mode.
Expand All @@ -75,6 +92,7 @@ export const ThemeProvider = ({ children }) => {
*/
const enableLightMode = () => {
dispatch({ type: 'ENABLE_LIGHT_MODE' });
setStoredTheme(ThemeEnum.LIGHT);
};

const key = `themeContext + isDark=${state.isDark} + isLight=${state.isLight}`;
Expand Down
16 changes: 16 additions & 0 deletions packages/app/theme/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { extendTheme } from 'native-base';
import { DefaultTheme } from 'react-native-paper';
import { type ThemeType } from './types';

export const theme = {
colors: {
Expand Down Expand Up @@ -127,3 +128,18 @@ export const darkPaperTheme = {
},
},
};

/**
* Get theme object by theme type eg light, dark... etc
* @param {ThemeType} themeType
* @returns {object}
*/
export const getTheme = (themeType: ThemeType) => {
switch (themeType) {
case 'DARK':
return darkTheme;
// extend types here
default:
return theme;
}
};
7 changes: 7 additions & 0 deletions packages/app/theme/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export enum ThemeEnum {
DARK = 'DARK',
LIGHT = 'LIGHT',
// add more types here
}

export type ThemeType = `${ThemeEnum}`;
Loading