| | |
| | | class UserSettings { |
| | | constructor() { |
| | | this.cache = new window.jvbCache('settings'); |
| | | this.cache.loadFromCache(); |
| | | this.findSettings(); |
| | | |
| | | this.debouncer = window.debouncer; |
| | | |
| | | this.isLoggedIn = jvbSettings.currentUser !== null; |
| | | 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) { |
| | | this.cache.setItem(name, value); |
| | | if (this.isLoggedIn) { |
| | | 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); |
| | | } |
| | | } |
| | | |
| | | loadSetting(name) { |
| | | let value = this.cache.getItem(name); |
| | | |
| | | if (this.isLoggedIn) { |
| | | |
| | | 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) { |
| | |
| | | } |
| | | } |
| | | |
| | | document.addEventListener('DOMContentLoaded', function() { |
| | | 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 (jvbSettings.currentUser !== null) { |
| | | try { |
| | | await fetch(`${jvbSettings.api}settings`, { |
| | | method: 'POST', |
| | | headers: { |
| | | 'Content-Type': 'application/json', |
| | | 'X-WP-Nonce': jvbSettings.nonce, |
| | | 'action_nonce': jvbSettings.dash, |
| | | }, |
| | | body: JSON.stringify({ |
| | | dark_mode: isDark, |
| | | user: jvbSettings.currentUser |
| | | }) |
| | | }); |
| | | } 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; |
| | | 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(), |
| | | // '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; |
| | | // } |
| | | // }); |
| | | // }); |