From 0e4b986e81f8132a44e61fa8df18860301cc3468 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Thu, 01 Jan 2026 20:31:10 +0000
Subject: [PATCH] =JakeVan preliminary additions
---
assets/js/concise/UserSettings.js | 240 ++++++++++++++++++++++++++++++++++++++++++------------------
1 files changed, 168 insertions(+), 72 deletions(-)
diff --git a/assets/js/concise/UserSettings.js b/assets/js/concise/UserSettings.js
index 91e950e..9c9f2b0 100644
--- a/assets/js/concise/UserSettings.js
+++ b/assets/js/concise/UserSettings.js
@@ -1,38 +1,130 @@
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) {
@@ -60,68 +152,72 @@
}
}
-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;
+// }
+// });
+// });
--
Gitblit v1.10.0