class UserSettings { constructor() { this.cache = new window.jvbCache('settings'); this.cache.loadFromCache(); this.findSettings(); this.debouncer = window.debouncer; this.isLoggedIn = window.auth.getUser() !== null; this.initListeners(); this.loadSettings(); this.subscribers = new Set(); } findSettings() { this.settings = document.querySelectorAll('[data-setting]')??[]; } addSetting(element, name = '', value = null) { name = name === '' ? element.name : name; element.dataset.setting = name; let cached = this.cache.get(name); if (cached) { if (element.tagName === 'INPUT' && ['checkbox', 'radio'].includes(element.type)) { element.checked = (cached === element.value); } else if (element.tagName === 'DETAILS') { element.open = (cached === 'on'); } } this.debouncer.schedule( 'add-setting', () => { this.findSettings.bind(this); }, 300 ); } loadSettings() { for (const input of this.settings) { let setting = input.name; if (Object.hasOwn(input.dataset, 'theme')) { this.checkTheme(input); } else { let stored = this.cache.get(setting); if (stored) { if (input.value === 'on') { input.checked = stored === 'on'; } else if (['checkbox', 'radio'].includes(input.tagName)) { input.checked = input.value === stored; } else { input.value = stored; } } } } } checkTheme(themeSwitch) { const prefersDark = window.matchMedia('(prefers-color-scheme: dark)'); let stored = this.cache.get('dark-mode'); if (prefersDark && (!stored || stored !== 'off')) { themeSwitch.checked = true; } else if (stored === 'on') { themeSwitch.checked = true; } } initListeners() { this.changeHandler = this.handleChange.bind(this); document.addEventListener('change', this.changeHandler); } handleChange(e) { if (!Object.hasOwn(e.target.dataset, 'setting')) { return; } let value = e.target.value; if (e.target.value === 'on') { value = e.target.checked ? 'on' : 'off'; } this.saveSetting(e.target.name, value); } saveSetting(name, value) { let old; if (this.isLoggedIn){ old = this.cache.get(name); } this.cache.set(name, value); if (this.isLoggedIn && old && old !== value) { this.saveToServer(name, value); } } async saveToServer(name, value) { if (!this.isLoggedIn || !['dark-mode'].includes(name)){ return; } const headers = { 'X-WP-Nonce': window.auth.getNonce(), 'Content-Type': 'application/json' }; const body = { user: window.auth.getUser(), setting: name, value: value }; const response = await fetch( `${jvbSettings.api}settings`, { method: 'POST', headers: headers, body: JSON.stringify(body) } ); const result = await response.json(); } loadSetting(name) { return this.cache.get(name); } loadUserSetting(name) { } /** * Event system */ subscribe(callback) { this.subscribers.add(callback); return () => this.subscribers.delete(callback); } notify(event, data) { this.subscribers.forEach(cb => cb(event, data)); } /*************************************************** CLEANUP ***************************************************/ destroy() { document.removeEventListener('change', this.changeHandler); this.subscribers.clear(); } } document.addEventListener('DOMContentLoaded', async function() { window.auth.subscribe((event) => { if (event === 'auth-loaded') { window.jvbUserSettings = new UserSettings(); } }); }); // // // Theme switching functionality // document.addEventListener('DOMContentLoaded', function() { // console.log('Theme switch initiated'); // const themeSwitch = document.getElementById('theme-switch'); // // if (!themeSwitch) return; // // // Initialize theme from localStorage or system preference // const prefersDark = window.matchMedia('(prefers-color-scheme: dark)'); // const storedTheme = localStorage.getItem('theme'); // // if (storedTheme) { // document.documentElement.classList.toggle('dark', storedTheme === 'dark'); // themeSwitch.checked = storedTheme === 'dark'; // } else { // document.documentElement.classList.toggle('dark', prefersDark.matches); // themeSwitch.checked = prefersDark.matches; // } // // // Handle theme switch changes // themeSwitch.addEventListener('change', async function () { // const isDark = this.checked; // document.documentElement.classList.toggle('dark', isDark); // localStorage.setItem('theme', isDark ? 'dark' : 'light'); // // // If user is logged in, save preference // if (window.auth.getUser() !== null) { // try { // await fetch(`${jvbSettings.api}settings`, { // method: 'POST', // headers: { // 'Content-Type': 'application/json', // 'X-WP-Nonce': window.auth.getNonce(), // 'X-Action-Nonce': window.auth.getNonce('dash'), // }, // body: JSON.stringify({ // dark_mode: isDark, // user: window.auth.getUser() // }) // }); // } catch (error) { // console.error('Failed to save theme preference:', error); // } // } // // // Update label // const label = document.getElementById('theme-switch'); // if (label) { // label.title = isDark ? 'Toggle Light Mode' : 'Toggle Dark Mode'; // } // }); // // // Handle system theme changes // prefersDark.addEventListener('change', (e) => { // if (!localStorage.getItem('theme')) { // const isDark = e.matches; // document.documentElement.classList.toggle('dark', isDark); // themeSwitch.checked = isDark; // } // }); // });