1/** 2 * Settings - Appearance Tab 3 * Activity tracking, dark mode, colorblind mode, and eye comfort toggles. 4 * Preferences persist to localStorage and update the DOM immediately. 5 */ 6 7import activityTracker from '../../services/activity-tracker.js'; 8import { clearAllActivity } from '../../api/activity.js'; 9import { afterRender } from '../../utils/dom.js'; 10 11export async function init() { 12 const content = document.getElementById('settings-content'); 13 const tmpl = $.templates('#tpl-tab-appearance'); 14 content.innerHTML = tmpl.render({}); 15 afterRender(content); 16 17 initToggles(); 18} 19 20function initToggles() { 21 const activityToggle = document.getElementById('toggleActivityTracking'); 22 const darkToggle = document.getElementById('toggleDarkMode'); 23 const cbToggle = document.getElementById('toggleColorblind'); 24 const comfortToggle = document.getElementById('toggleComfort'); 25 26 // Sync initial state from current DOM/localStorage 27 try { 28 if (activityToggle) activityToggle.checked = activityTracker.isEnabled(); 29 30 const savedTheme = localStorage.getItem('theme'); 31 const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; 32 const isDark = savedTheme === 'dark' || (!savedTheme && prefersDark); 33 if (darkToggle) darkToggle.checked = isDark; 34 35 const savedCb = localStorage.getItem('colorblindMode'); 36 if (cbToggle) cbToggle.checked = savedCb === 'true'; 37 38 const savedComfort = localStorage.getItem('comfortMode'); 39 if (comfortToggle) comfortToggle.checked = savedComfort === 'true'; 40 } catch { /* localStorage unavailable */ } 41 42 // Activity tracking 43 activityToggle?.addEventListener('change', () => { 44 activityTracker.setEnabled(activityToggle.checked); 45 }); 46 47 // Clear activity history 48 const clearBtn = document.getElementById('btnClearActivity'); 49 clearBtn?.addEventListener('click', () => { 50 clearAllActivity(); 51 window.showToast?.('Cleared', 'success', { description: 'Activity history has been cleared' }); 52 }); 53 54 // Dark mode 55 darkToggle?.addEventListener('change', () => { 56 const newTheme = darkToggle.checked ? 'dark' : 'light'; 57 document.documentElement.setAttribute('data-theme', newTheme); 58 try { localStorage.setItem('theme', newTheme); } catch { /* ignore */ } 59 }); 60 61 // Colorblind mode 62 cbToggle?.addEventListener('change', () => { 63 const isEnabled = cbToggle.checked; 64 if (isEnabled) { 65 document.documentElement.setAttribute('data-cb-mode', 'on'); 66 } else { 67 document.documentElement.removeAttribute('data-cb-mode'); 68 } 69 try { localStorage.setItem('colorblindMode', isEnabled ? 'true' : 'false'); } catch { /* ignore */ } 70 }); 71 72 // Eye comfort mode 73 comfortToggle?.addEventListener('change', () => { 74 const isEnabled = comfortToggle.checked; 75 if (isEnabled) { 76 document.documentElement.setAttribute('data-comfort-mode', 'on'); 77 } else { 78 document.documentElement.removeAttribute('data-comfort-mode'); 79 } 80 try { localStorage.setItem('comfortMode', isEnabled ? 'true' : 'false'); } catch { /* ignore */ } 81 }); 82} 83 84export function destroy() { 85 // No cleanup needed â toggles apply immediately via localStorage 86}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.