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;
|
// }
|
// });
|
// });
|