export class SettingsManager { constructor() { this.themeManager = new ThemeManager(); this.layoutManager = new LayoutManager(); this.fontManager = new FontManager(); this.settingsButton = document.querySelector('.settings-button'); this.init(); } init() { this.attachEventListeners(); this.loadSavedSettings(); this.setupDataManagement(); } attachEventListeners() { const settingsPopup = document.getElementById('settingsPopup'); const closeSettings = document.querySelector('.close-settings'); this.settingsButton.addEventListener('click', () => { settingsPopup.classList.add('show'); this.settingsButton.classList.add('disabled'); }); const closeSettingsHandler = () => { settingsPopup.classList.remove('show'); this.settingsButton.classList.remove('disabled'); }; closeSettings.addEventListener('click', closeSettingsHandler); settingsPopup.addEventListener('click', (e) => { if (e.target === settingsPopup) { closeSettingsHandler(); } }); // Add escape key handler document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && settingsPopup.classList.contains('show')) { closeSettingsHandler(); } }); } loadSavedSettings() { // Load CSS const customCSSEditor = document.getElementById('customCSS'); customCSSEditor.value = localStorage.getItem('customCSS') || ''; this.applyCustomCSS(); // Load theme const savedTheme = localStorage.getItem('theme') || 'mocha'; this.themeManager.setTheme(savedTheme); // Load layout const savedLayout = localStorage.getItem('layout') || 'grid'; this.layoutManager.setLayout(savedLayout); // Load font const savedFont = localStorage.getItem('font'); if (savedFont) { this.fontManager.setFont(savedFont); } } applyCustomCSS() { const customCSSEditor = document.getElementById('customCSS'); let customStyle = document.getElementById('custom-css') || document.createElement('style'); customStyle.id = 'custom-css'; customStyle.textContent = customCSSEditor.value; document.head.appendChild(customStyle); } setupDataManagement() { document.getElementById('exportData').addEventListener('click', () => this.exportAllData()); document.getElementById('importData').addEventListener('click', () => { document.getElementById('importDataFile').click(); }); document.getElementById('importDataFile').addEventListener('change', (e) => { if (e.target.files[0]) this.importAllData(e.target.files[0]); }); } async exportAllData() { const data = { version: '1.0.0', exportDate: new Date().toISOString(), settings: { theme: localStorage.getItem('theme'), layout: localStorage.getItem('layout'), font: localStorage.getItem('font'), linkSize: localStorage.getItem('linkSize'), username: localStorage.getItem('username'), background: localStorage.getItem('background'), customCSS: localStorage.getItem('customCSS') }, links: JSON.parse(localStorage.getItem('customLinks') || '{}'), shortcuts: JSON.parse(localStorage.getItem('shortcuts') || '{}'), searchEngines: JSON.parse(localStorage.getItem('searchEngines') || '[]'), customIcons: JSON.parse(localStorage.getItem('customIcons') || '{}') }; const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `startpage-backup-${new Date().toISOString().split('T')[0]}.json`; a.click(); URL.revokeObjectURL(url); } async importAllData(file) { try { const text = await file.text(); const data = JSON.parse(text); if (!data.version) { throw new Error('Invalid backup file format'); } // Confirm import if (!confirm('This will override all your current settings. Continue?')) { return; } // Import settings Object.entries(data.settings).forEach(([key, value]) => { if (value !== null) localStorage.setItem(key, value); }); // Import data localStorage.setItem('customLinks', JSON.stringify(data.links)); localStorage.setItem('shortcuts', JSON.stringify(data.shortcuts)); localStorage.setItem('searchEngines', JSON.stringify(data.searchEngines)); localStorage.setItem('customIcons', JSON.stringify(data.customIcons)); // Reload page to apply changes alert('Settings imported successfully. The page will now reload.'); window.location.reload(); } catch (error) { console.error('Failed to import data:', error); alert('Failed to import settings. Make sure the file is a valid backup.'); } } } class ThemeManager { constructor() { this.themeSelect = document.getElementById('themeSelect'); this.init(); } init() { this.themeSelect.addEventListener('change', (e) => { this.setTheme(e.target.value); }); } setTheme(theme) { const root = document.documentElement; root.style.setProperty('--base', `var(--${theme}-base)`); root.style.setProperty('--base-rgb', `var(--${theme}-base-rgb)`); root.style.setProperty('--surface0', `var(--${theme}-surface0)`); root.style.setProperty('--surface1', `var(--${theme}-surface1)`); root.style.setProperty('--text', `var(--${theme}-text)`); root.style.setProperty('--blue', `var(--${theme}-blue)`); root.style.setProperty('--pink', `var(--${theme}-pink)`); localStorage.setItem('theme', theme); this.themeSelect.value = theme; } } class LayoutManager { constructor() { this.layoutSelect = document.getElementById('layoutSelect'); this.init(); } init() { this.layoutSelect.addEventListener('change', (e) => { this.setLayout(e.target.value); }); } setLayout(layout) { document.body.setAttribute('data-layout', layout); localStorage.setItem('layout', layout); this.layoutSelect.value = layout; } } class FontManager { constructor() { this.fontSelect = document.getElementById('fontSelect'); this.init(); } init() { this.fontSelect.addEventListener('change', (e) => { this.setFont(e.target.value); }); } setFont(font) { document.documentElement.style.setProperty('--font-family', font); if (font === 'MapleMono') { document.documentElement.style.setProperty('--font-mono', 'MapleMono'); } localStorage.setItem('font', font); this.fontSelect.value = font; } }