61 lines
1.9 KiB
JavaScript
61 lines
1.9 KiB
JavaScript
import React, { createContext, useState, useMemo, useContext, useEffect } from 'react';
|
|
import { ThemeProvider as MuiThemeProvider } from '@mui/material/styles';
|
|
import { lightTheme, darkTheme, discordTheme } from '../themes';
|
|
import { UserContext } from './UserContext';
|
|
import { post } from '../lib/api';
|
|
|
|
export const ThemeContext = createContext();
|
|
|
|
export const ThemeProvider = ({ children }) => {
|
|
const { user } = useContext(UserContext);
|
|
const [themeName, setThemeName] = useState(localStorage.getItem('themeName') || 'discord');
|
|
|
|
useEffect(() => {
|
|
// Prefer an explicit user selection (stored in localStorage) over defaults or server values.
|
|
// Behavior:
|
|
// - If localStorage has a themeName, use that (user's explicit choice always wins).
|
|
// - Else if the authenticated user has a server-side preference, adopt that and persist it locally.
|
|
// - Else (first visit, no local choice and no server preference) use default 'discord'.
|
|
const storedTheme = localStorage.getItem('themeName');
|
|
if (storedTheme) {
|
|
setThemeName(storedTheme);
|
|
return;
|
|
}
|
|
|
|
if (user && user.theme) {
|
|
setThemeName(user.theme);
|
|
localStorage.setItem('themeName', user.theme);
|
|
return;
|
|
}
|
|
|
|
// First-time visitor: fall back to default
|
|
setThemeName('discord');
|
|
}, [user]);
|
|
|
|
const theme = useMemo(() => {
|
|
switch (themeName) {
|
|
case 'dark':
|
|
return darkTheme;
|
|
case 'discord':
|
|
return discordTheme;
|
|
default:
|
|
return lightTheme;
|
|
}
|
|
}, [themeName]);
|
|
|
|
const changeTheme = (name) => {
|
|
if (user) {
|
|
post('/api/user/theme', { userId: user.id, theme: name }).catch(() => {});
|
|
}
|
|
localStorage.setItem('themeName', name);
|
|
setThemeName(name);
|
|
};
|
|
|
|
return (
|
|
<ThemeContext.Provider value={{ themeName, changeTheme }}>
|
|
<MuiThemeProvider theme={theme}>
|
|
{children}
|
|
</MuiThemeProvider>
|
|
</ThemeContext.Provider>
|
|
);
|
|
}; |