69 lines
2.3 KiB
TypeScript
69 lines
2.3 KiB
TypeScript
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
|
import { ThemeType } from '../../types/theme';
|
|
import {
|
|
LIGHT_THEME,
|
|
DARK_THEME,
|
|
PINK_THEME,
|
|
BLUE_THEME,
|
|
GREEN_THEME,
|
|
PURPLE_THEME,
|
|
THEMES,
|
|
getNextTheme
|
|
} from '../../utils/themes';
|
|
|
|
// Ключ для хранения текущей темы в localStorage
|
|
const THEME_STORAGE_KEY = 'journal-pl-theme';
|
|
|
|
// Получаем сохраненную тему из localStorage или используем светлую тему по умолчанию
|
|
const getSavedTheme = (): ThemeType => {
|
|
if (typeof window !== 'undefined') {
|
|
const savedTheme = localStorage.getItem(THEME_STORAGE_KEY) as ThemeType | null;
|
|
if (savedTheme && THEMES.includes(savedTheme as ThemeType)) {
|
|
return savedTheme as ThemeType;
|
|
}
|
|
}
|
|
// По умолчанию используем светлую тему
|
|
return LIGHT_THEME;
|
|
};
|
|
|
|
interface ThemeState {
|
|
currentTheme: ThemeType;
|
|
}
|
|
|
|
const initialState: ThemeState = {
|
|
currentTheme: getSavedTheme(),
|
|
};
|
|
|
|
export const themeSlice = createSlice({
|
|
name: 'theme',
|
|
initialState,
|
|
reducers: {
|
|
setTheme: (state, action: PayloadAction<ThemeType>) => {
|
|
state.currentTheme = action.payload;
|
|
|
|
// Сохраняем выбранную тему в localStorage
|
|
if (typeof window !== 'undefined') {
|
|
localStorage.setItem(THEME_STORAGE_KEY, action.payload);
|
|
}
|
|
},
|
|
cycleNextTheme: (state) => {
|
|
state.currentTheme = getNextTheme(state.currentTheme);
|
|
|
|
// Сохраняем выбранную тему в localStorage
|
|
if (typeof window !== 'undefined') {
|
|
localStorage.setItem(THEME_STORAGE_KEY, state.currentTheme);
|
|
}
|
|
},
|
|
},
|
|
});
|
|
|
|
export const { setTheme, cycleNextTheme } = themeSlice.actions;
|
|
|
|
// Селекторы для получения информации о текущей теме
|
|
export const selectCurrentTheme = (state: { theme: ThemeState }) => state.theme.currentTheme;
|
|
export const selectIsLightVariant = (state: { theme: ThemeState }) =>
|
|
[LIGHT_THEME, PINK_THEME, BLUE_THEME, GREEN_THEME].includes(state.theme.currentTheme);
|
|
export const selectIsDarkVariant = (state: { theme: ThemeState }) =>
|
|
[DARK_THEME, PURPLE_THEME].includes(state.theme.currentTheme);
|
|
|
|
export default themeSlice.reducer;
|