mcp-quiz-server
Version:
🧠AI-Powered Quiz Management via Model Context Protocol (MCP) - Create, manage, and take quizzes directly from VS Code, Claude, and other AI agents.
85 lines • 2.66 kB
JavaScript
export class ThemeService {
constructor() {
this.listeners = new Set();
this.currentTheme = this.loadThemeFromStorage();
this.initializeSystemThemeListener();
}
static getInstance() {
if (!ThemeService.instance) {
ThemeService.instance = new ThemeService();
}
return ThemeService.instance;
}
loadThemeFromStorage() {
const saved = localStorage.getItem('quiz-theme');
if (saved) {
try {
const parsed = JSON.parse(saved);
return { mode: parsed.mode || 'system', color: 'slate' };
}
catch (e) {
console.warn('Invalid theme data in localStorage');
}
}
return { mode: 'system', color: 'slate' };
}
saveThemeToStorage() {
localStorage.setItem('quiz-theme', JSON.stringify(this.currentTheme));
}
initializeSystemThemeListener() {
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
if (this.currentTheme.mode === 'system') {
this.applyTheme();
}
});
}
getTheme() {
return { ...this.currentTheme };
}
setMode(mode) {
this.currentTheme.mode = mode;
this.applyTheme();
this.saveThemeToStorage();
this.notifyListeners();
}
setColor(color) {
this.currentTheme.color = color;
this.applyTheme();
this.saveThemeToStorage();
this.notifyListeners();
}
toggleDarkMode() {
const newMode = this.currentTheme.mode === 'dark' ? 'light' : 'dark';
this.setMode(newMode);
}
applyTheme() {
const html = document.documentElement;
html.classList.remove('dark');
if (this.currentTheme.mode === 'dark') {
html.classList.add('dark');
}
else if (this.currentTheme.mode === 'system') {
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
if (prefersDark) {
html.classList.add('dark');
}
}
document.body.classList.add('theme-transition');
setTimeout(() => {
document.body.classList.remove('theme-transition');
}, 300);
}
subscribe(callback) {
this.listeners.add(callback);
return () => {
this.listeners.delete(callback);
};
}
notifyListeners() {
this.listeners.forEach(callback => callback(this.getTheme()));
}
initialize() {
this.applyTheme();
}
}
//# sourceMappingURL=ThemeService.js.map