Skip to content

Commit

Permalink
fix: persist user selected theme, fixes #2789
Browse files Browse the repository at this point in the history
  • Loading branch information
edu-stx committed Nov 3, 2022
1 parent e285c51 commit 43014b7
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 5 deletions.
22 changes: 18 additions & 4 deletions src/app/common/theme-provider.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { createContext, Dispatch, SetStateAction, useContext, useEffect, useState } from 'react';
import { createContext, useContext, useEffect, useState } from 'react';

import { store } from '@app/store';
import { userSelectedThemeActions } from '@app/store/settings/settings.actions';
import { useUserSelectedTheme } from '@app/store/settings/settings.selectors';

export const themeLabelMap = {
light: 'Light',
Expand All @@ -16,7 +20,7 @@ export const getThemeLabel = (theme: UserSelectedTheme) => {
const ThemeContext = createContext<{
theme: ComputedTheme;
userSelectedTheme: UserSelectedTheme;
setUserSelectedTheme: Dispatch<SetStateAction<UserSelectedTheme>>;
setUserSelectedTheme: (theme: UserSelectedTheme) => void;
}>({
// These values are not used, but are set to satisfy the context's value type.
theme: 'light',
Expand All @@ -27,12 +31,22 @@ const ThemeContext = createContext<{
const getSystemTheme = () =>
window.matchMedia('prefers-color-scheme: dark').matches ? 'dark' : 'light';

function getComputedTheme(userSelectedTheme: UserSelectedTheme): ComputedTheme {
if (userSelectedTheme === 'system') return getSystemTheme();

return userSelectedTheme;
}

function setUserSelectedTheme(theme: UserSelectedTheme) {
store.dispatch(userSelectedThemeActions.setUserSelectedTheme(theme));
}

interface ThemeSwitcherProviderProps {
children: JSX.Element | JSX.Element[];
}
export const ThemeSwitcherProvider = ({ children }: ThemeSwitcherProviderProps) => {
const [userSelectedTheme, setUserSelectedTheme] = useState<UserSelectedTheme>('system');
const [theme, setTheme] = useState<ComputedTheme>(() => getSystemTheme());
const userSelectedTheme = useUserSelectedTheme();
const [theme, setTheme] = useState<ComputedTheme>(() => getComputedTheme(userSelectedTheme));

useEffect(() => {
switch (userSelectedTheme) {
Expand Down
4 changes: 3 additions & 1 deletion src/app/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { onboardingSlice } from './onboarding/onboarding.slice';
import { analyticsSlice } from './analytics/analytics.slice';
import { submittedTransactionsSlice } from './submitted-transactions/submitted-transactions.slice';
import { networksSlice } from './networks/networks.slice';
import { settingsSlice } from './settings/settings.slice';

const storage = new ExtensionStorage(chrome.storage.local, chrome.runtime);

Expand All @@ -37,14 +38,15 @@ const rootReducer = combineReducers({
networks: networksSlice.reducer,
onboarding: onboardingSlice.reducer,
submittedTransactions: submittedTransactionsSlice.reducer,
settings: settingsSlice.reducer,
});

const persistConfig = {
key: 'root',
version: 1,
storage,
serialize: true,
whitelist: ['analytics', 'chains', 'keys', 'networks', 'onboarding'],
whitelist: ['analytics', 'chains', 'keys', 'networks', 'onboarding', 'settings'],
};

const persistedReducer = persistReducer(persistConfig, rootReducer);
Expand Down
3 changes: 3 additions & 0 deletions src/app/store/settings/settings.actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { settingsSlice } from './settings.slice';

export const userSelectedThemeActions = settingsSlice.actions;
12 changes: 12 additions & 0 deletions src/app/store/settings/settings.selectors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { createSelector } from '@reduxjs/toolkit';
import { useSelector } from 'react-redux';

import { RootState } from '@app/store';

const selectSettings = (state: RootState) => state.settings;

const selectUserSelectedTheme = createSelector(selectSettings, state => state.userSelectedTheme);

export function useUserSelectedTheme() {
return useSelector(selectUserSelectedTheme);
}
20 changes: 20 additions & 0 deletions src/app/store/settings/settings.slice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { UserSelectedTheme } from '@app/common/theme-provider';
import { createSlice, PayloadAction } from '@reduxjs/toolkit';

interface InitialState {
userSelectedTheme: UserSelectedTheme;
}

const initialState: InitialState = {
userSelectedTheme: 'system',
};

export const settingsSlice = createSlice({
name: 'settings',
initialState,
reducers: {
setUserSelectedTheme(state, action: PayloadAction<UserSelectedTheme>) {
state.userSelectedTheme = action.payload;
},
},
});

0 comments on commit 43014b7

Please sign in to comment.