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.
251 lines • 8.1 kB
JavaScript
export class SettingsManager {
constructor() {
this.changeListeners = [];
this.STORAGE_KEY = 'quiz-platform-settings';
this.settings = this.getDefaultSettings();
this.loadSettings();
}
static getInstance() {
if (!SettingsManager.instance) {
SettingsManager.instance = new SettingsManager();
}
return SettingsManager.instance;
}
getDefaultSettings() {
return {
ui: {
theme: 'system',
fontSize: 'medium',
navigationVisible: true,
reducedMotion: false,
animations: true,
celebration: true,
announceChanges: false,
},
quiz: {
viewMode: 'single',
autoAdvance: {
enabled: false,
delaySeconds: 3,
showCountdown: true,
},
showProgress: true,
largeButtons: false,
preloadQuestions: true,
minimalUI: false,
},
accessibility: {
screenReaderMode: false,
keyboardNavigation: true,
skipLinks: false,
highContrast: false,
},
performance: {
lazyLoading: true,
compactMode: false,
disableAnalytics: false,
cacheOptimized: true,
},
};
}
loadSettings() {
try {
const stored = localStorage.getItem(this.STORAGE_KEY);
if (stored) {
const parsedSettings = JSON.parse(stored);
this.settings = this.mergeWithDefaults(parsedSettings);
console.log('⚙️ Settings loaded from localStorage:', this.settings);
}
}
catch (error) {
console.warn('Failed to load settings from localStorage:', error);
this.settings = this.getDefaultSettings();
}
}
mergeWithDefaults(stored) {
const defaults = this.getDefaultSettings();
return {
ui: { ...defaults.ui, ...stored.ui },
quiz: {
...defaults.quiz,
...stored.quiz,
autoAdvance: { ...defaults.quiz.autoAdvance, ...stored.quiz?.autoAdvance },
},
accessibility: { ...defaults.accessibility, ...stored.accessibility },
performance: { ...defaults.performance, ...stored.performance },
};
}
saveSettings() {
try {
localStorage.setItem(this.STORAGE_KEY, JSON.stringify(this.settings));
console.log('💾 Settings saved to localStorage');
}
catch (error) {
console.error('Failed to save settings to localStorage:', error);
}
}
getSettings() {
return { ...this.settings };
}
getSetting(path) {
return this.getNestedValue(this.settings, path);
}
updateSetting(path, value) {
const oldSettings = { ...this.settings };
this.setNestedValue(this.settings, path, value);
this.saveSettings();
this.notifyChangeListeners();
console.log(`⚙️ Setting updated: ${path} =`, value);
}
applyBulkSettings(newSettings) {
const oldSettings = { ...this.settings };
this.settings = this.mergeWithDefaults(newSettings);
this.saveSettings();
this.notifyChangeListeners();
console.log('⚙️ Bulk settings applied:', newSettings);
}
resetToDefaults() {
this.settings = this.getDefaultSettings();
this.saveSettings();
this.notifyChangeListeners();
console.log('🔄 Settings reset to defaults');
}
subscribe(listener) {
this.changeListeners.push(listener);
return () => {
const index = this.changeListeners.indexOf(listener);
if (index > -1) {
this.changeListeners.splice(index, 1);
}
};
}
notifyChangeListeners() {
this.changeListeners.forEach(listener => {
try {
listener(this.getSettings());
}
catch (error) {
console.error('Error in settings change listener:', error);
}
});
}
exportSettings() {
return JSON.stringify(this.settings, null, 2);
}
importSettings(jsonString) {
try {
const importedSettings = JSON.parse(jsonString);
this.applyBulkSettings(importedSettings);
return true;
}
catch (error) {
console.error('Failed to import settings:', error);
return false;
}
}
validateSettings(settings) {
try {
return (typeof settings === 'object' &&
settings.ui &&
typeof settings.ui === 'object' &&
settings.quiz &&
typeof settings.quiz === 'object' &&
settings.accessibility &&
typeof settings.accessibility === 'object' &&
settings.performance &&
typeof settings.performance === 'object');
}
catch {
return false;
}
}
getNestedValue(obj, path) {
return path.split('.').reduce((current, key) => current?.[key], obj);
}
setNestedValue(obj, path, value) {
const keys = path.split('.');
const lastKey = keys.pop();
const target = keys.reduce((current, key) => {
if (!current[key] || typeof current[key] !== 'object') {
current[key] = {};
}
return current[key];
}, obj);
target[lastKey] = value;
}
getUISettings() {
return { ...this.settings.ui };
}
getQuizSettings() {
return { ...this.settings.quiz };
}
getAccessibilitySettings() {
return { ...this.settings.accessibility };
}
getPerformanceSettings() {
return { ...this.settings.performance };
}
applyAccessibilityMode() {
this.applyBulkSettings({
ui: {
theme: 'high-contrast',
fontSize: 'large',
navigationVisible: true,
reducedMotion: true,
animations: false,
celebration: false,
announceChanges: true,
},
accessibility: {
screenReaderMode: true,
keyboardNavigation: true,
skipLinks: true,
highContrast: true,
},
quiz: {
viewMode: 'single',
autoAdvance: {
enabled: false,
delaySeconds: 5,
showCountdown: true,
},
showProgress: true,
largeButtons: true,
preloadQuestions: true,
minimalUI: false,
},
});
}
applyPerformanceMode() {
this.applyBulkSettings({
ui: {
theme: 'light',
fontSize: 'medium',
navigationVisible: false,
reducedMotion: true,
animations: false,
celebration: false,
announceChanges: false,
},
quiz: {
viewMode: 'single',
autoAdvance: {
enabled: true,
delaySeconds: 1,
showCountdown: false,
},
showProgress: false,
largeButtons: false,
preloadQuestions: false,
minimalUI: true,
},
performance: {
lazyLoading: true,
compactMode: true,
disableAnalytics: true,
cacheOptimized: true,
},
});
}
}
//# sourceMappingURL=SettingsManager.js.map