377 lines
No EOL
14 KiB
JavaScript
Executable file
377 lines
No EOL
14 KiB
JavaScript
Executable file
import { Clock } from './modules/Clock.js';
|
|
import { LinksManager } from './modules/LinksManager.js';
|
|
import { SearchEngineManager } from './modules/SearchManager.js';
|
|
import { ShortcutManager } from './modules/ShortcutManager.js';
|
|
import { SettingsManager } from './modules/SettingsManager.js';
|
|
|
|
// Make managers available globally
|
|
window.linksManager = null;
|
|
window.searchManager = null;
|
|
window.shortcutManager = null;
|
|
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
// Debug Font Awesome loading
|
|
const testIcon = document.createElement('i');
|
|
testIcon.className = 'fas fa-check';
|
|
console.log('Font Awesome test:', window.getComputedStyle(testIcon).fontFamily);
|
|
|
|
// Initialize clock
|
|
const clock = new Clock(
|
|
document.getElementById('clock'),
|
|
document.getElementById('greeting')
|
|
);
|
|
clock.start();
|
|
|
|
// Initialize settings
|
|
const settings = new SettingsManager();
|
|
|
|
// Focus search on load
|
|
document.getElementById('search-input').focus();
|
|
|
|
// Name handling
|
|
const nameInput = document.getElementById('nameInput');
|
|
const saveNameBtn = document.getElementById('saveName');
|
|
|
|
// Load saved name
|
|
const savedName = localStorage.getItem('username');
|
|
if (savedName) {
|
|
nameInput.value = savedName;
|
|
}
|
|
|
|
// Save name
|
|
saveNameBtn.addEventListener('click', () => {
|
|
const name = nameInput.value.trim();
|
|
if (name) {
|
|
localStorage.setItem('username', name);
|
|
} else {
|
|
localStorage.removeItem('username');
|
|
nameInput.value = ''; // Clear input if empty
|
|
}
|
|
clock.updateGreeting();
|
|
});
|
|
|
|
// Also handle Enter key in name input
|
|
nameInput.addEventListener('keypress', (e) => {
|
|
if (e.key === 'Enter') {
|
|
e.preventDefault();
|
|
saveNameBtn.click();
|
|
}
|
|
});
|
|
|
|
// Background handling
|
|
const fileInput = document.getElementById('bgImage');
|
|
const removeButton = document.getElementById('removeButton');
|
|
const presetOptions = document.querySelectorAll('.preset-bg-option');
|
|
|
|
function setBackground(url) {
|
|
document.body.style.backgroundImage = url ? `url(${url})` : 'none';
|
|
localStorage.setItem('background', url || '');
|
|
|
|
// Update active state of preset options
|
|
presetOptions.forEach(option => {
|
|
const optionBg = option.dataset.bg;
|
|
option.classList.toggle('active', optionBg === (url || 'none'));
|
|
});
|
|
}
|
|
|
|
// Load saved background
|
|
const savedBg = localStorage.getItem('background');
|
|
if (savedBg) {
|
|
setBackground(savedBg);
|
|
}
|
|
|
|
// Handle preset backgrounds
|
|
presetOptions.forEach(option => {
|
|
const bgUrl = option.dataset.bg;
|
|
|
|
// Add none class for the no-background option
|
|
if (bgUrl === 'none') {
|
|
option.classList.add('none');
|
|
} else {
|
|
// Set preview image
|
|
option.style.backgroundImage = `url(${bgUrl})`;
|
|
|
|
// Preload image
|
|
const img = new Image();
|
|
img.src = bgUrl;
|
|
}
|
|
|
|
option.addEventListener('click', () => {
|
|
setBackground(bgUrl === 'none' ? '' : bgUrl);
|
|
});
|
|
});
|
|
|
|
// Handle custom upload
|
|
fileInput.addEventListener('change', (e) => {
|
|
const file = e.target.files[0];
|
|
if (file) {
|
|
const reader = new FileReader();
|
|
reader.onload = (e) => {
|
|
setBackground(e.target.result);
|
|
};
|
|
reader.readAsDataURL(file);
|
|
}
|
|
});
|
|
|
|
removeButton.addEventListener('click', () => {
|
|
setBackground('');
|
|
fileInput.value = '';
|
|
});
|
|
|
|
// Settings popup handling
|
|
const settingsButton = document.querySelector('.settings-button');
|
|
const settingsPopup = document.getElementById('settingsPopup');
|
|
const closeSettings = document.querySelector('.close-settings');
|
|
|
|
settingsButton.addEventListener('click', () => {
|
|
settingsPopup.classList.add('show');
|
|
});
|
|
|
|
closeSettings.addEventListener('click', () => {
|
|
settingsPopup.classList.remove('show');
|
|
});
|
|
|
|
// Close popup when clicking outside
|
|
settingsPopup.addEventListener('click', (e) => {
|
|
if (e.target === settingsPopup) {
|
|
settingsPopup.classList.remove('show');
|
|
}
|
|
});
|
|
|
|
// Theme handling
|
|
const themeSelect = document.getElementById('themeSelect');
|
|
|
|
const setTheme = (theme) => {
|
|
document.body.style.transition = 'background-color 0.3s ease';
|
|
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);
|
|
|
|
// Add smooth transition class
|
|
document.body.classList.add('theme-transition');
|
|
setTimeout(() => {
|
|
document.body.classList.remove('theme-transition');
|
|
}, 300);
|
|
};
|
|
|
|
// Load saved theme
|
|
const savedTheme = localStorage.getItem('theme') || 'mocha';
|
|
themeSelect.value = savedTheme;
|
|
setTheme(savedTheme);
|
|
|
|
// Handle theme changes
|
|
themeSelect.addEventListener('change', (e) => {
|
|
setTheme(e.target.value);
|
|
});
|
|
|
|
// Initialize managers globally
|
|
window.linksManager = new LinksManager();
|
|
window.searchManager = new SearchEngineManager();
|
|
window.shortcutManager = new ShortcutManager();
|
|
const shortcutManager = new ShortcutManager();
|
|
|
|
// Layout handling
|
|
const layoutSelect = document.getElementById('layoutSelect');
|
|
layoutSelect.addEventListener('change', (e) => {
|
|
document.body.setAttribute('data-layout', e.target.value);
|
|
localStorage.setItem('layout', e.target.value);
|
|
});
|
|
|
|
// Load saved layout
|
|
const savedLayout = localStorage.getItem('layout') || 'grid';
|
|
layoutSelect.value = savedLayout;
|
|
document.body.setAttribute('data-layout', savedLayout);
|
|
|
|
// Custom CSS handling
|
|
const customCSSEditor = document.getElementById('customCSS');
|
|
customCSSEditor.value = localStorage.getItem('customCSS') || '';
|
|
customCSSEditor.addEventListener('change', () => {
|
|
localStorage.setItem('customCSS', customCSSEditor.value);
|
|
applyCustomCSS();
|
|
});
|
|
|
|
function applyCustomCSS() {
|
|
let customStyle = document.getElementById('custom-css') || document.createElement('style');
|
|
customStyle.id = 'custom-css';
|
|
customStyle.textContent = customCSSEditor.value;
|
|
document.head.appendChild(customStyle);
|
|
}
|
|
|
|
// Apply custom CSS on load
|
|
applyCustomCSS();
|
|
|
|
// Font handling
|
|
const fontSelect = document.getElementById('fontSelect');
|
|
fontSelect.addEventListener('change', (e) => {
|
|
document.documentElement.style.setProperty('--font-family', e.target.value);
|
|
if (e.target.value === 'MapleMono') {
|
|
document.documentElement.style.setProperty('--font-mono', 'MapleMono');
|
|
}
|
|
localStorage.setItem('font', e.target.value);
|
|
});
|
|
|
|
// Load saved font
|
|
const savedFont = localStorage.getItem('font');
|
|
if (savedFont) {
|
|
fontSelect.value = savedFont;
|
|
document.documentElement.style.setProperty('--font-family', savedFont);
|
|
if (savedFont === 'MapleMono') {
|
|
document.documentElement.style.setProperty('--font-mono', 'MapleMono');
|
|
}
|
|
}
|
|
|
|
// Event delegation for settings actions
|
|
document.addEventListener('click', (e) => {
|
|
const action = e.target.dataset.action;
|
|
if (action) {
|
|
switch (action) {
|
|
case 'openSettings':
|
|
settingsPopup.classList.add('show');
|
|
break;
|
|
case 'closeSettings':
|
|
settingsPopup.classList.remove('show');
|
|
break;
|
|
case 'removeBackground':
|
|
setBackground('');
|
|
fileInput.value = '';
|
|
break;
|
|
case 'saveName':
|
|
const name = nameInput.value.trim();
|
|
if (name) {
|
|
localStorage.setItem('username', name);
|
|
} else {
|
|
localStorage.removeItem('username');
|
|
nameInput.value = ''; // Clear input if empty
|
|
}
|
|
clock.updateGreeting();
|
|
break;
|
|
case 'addCategory':
|
|
const categoryName = prompt('Enter category name:');
|
|
if (categoryName) linksManager.addCategory(categoryName);
|
|
break;
|
|
case 'addLink':
|
|
const category = prompt('Enter category:');
|
|
if (category && linksManager.links[category]) {
|
|
linksManager.addLink(category, {
|
|
name: 'New Link',
|
|
url: 'https://',
|
|
icon: 'fas fa-link'
|
|
});
|
|
}
|
|
break;
|
|
case 'exportLinks':
|
|
linksManager.export();
|
|
break;
|
|
case 'importLinks':
|
|
document.getElementById('importLinks').click();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
|
|
document.getElementById('importLinks').addEventListener('change', (e) => {
|
|
if (e.target.files[0]) linksManager.import(e.target.files[0]);
|
|
});
|
|
|
|
// Link size handling with reset functionality
|
|
const linkSizeControl = document.getElementById('linkSizeControl');
|
|
const linkSizeValue = document.getElementById('linkSizeValue');
|
|
const resetLinkSize = document.getElementById('resetLinkSize');
|
|
const DEFAULT_LINK_SIZE = 16;
|
|
|
|
const setLinkSize = (size) => {
|
|
document.documentElement.style.setProperty('--link-size', `${size}px`);
|
|
linkSizeValue.textContent = `${size}px`;
|
|
linkSizeControl.value = size;
|
|
localStorage.setItem('linkSize', size);
|
|
};
|
|
|
|
// Load saved link size or set default
|
|
const savedLinkSize = localStorage.getItem('linkSize') || DEFAULT_LINK_SIZE;
|
|
setLinkSize(parseInt(savedLinkSize));
|
|
|
|
// Update on change
|
|
linkSizeControl.addEventListener('input', (e) => {
|
|
setLinkSize(parseInt(e.target.value));
|
|
});
|
|
|
|
// Reset button handler
|
|
resetLinkSize.addEventListener('click', () => {
|
|
setLinkSize(DEFAULT_LINK_SIZE);
|
|
});
|
|
|
|
// Transparency and Blur controls
|
|
const transparencyControl = document.getElementById('transparencyControl');
|
|
const transparencyValue = document.getElementById('transparencyValue');
|
|
const resetTransparency = document.getElementById('resetTransparency');
|
|
const blurToggle = document.getElementById('blurToggle');
|
|
const blurControl = document.getElementById('blurControl');
|
|
const blurValue = document.getElementById('blurValue');
|
|
const resetBlur = document.getElementById('resetBlur');
|
|
|
|
const DEFAULT_TRANSPARENCY = 15;
|
|
const DEFAULT_BLUR = 8;
|
|
|
|
const setTransparency = (value) => {
|
|
const opacity = (100 - value) / 100;
|
|
document.documentElement.style.setProperty('--container-opacity', opacity);
|
|
transparencyValue.textContent = `${value}%`;
|
|
transparencyControl.value = value;
|
|
localStorage.setItem('transparency', value);
|
|
};
|
|
|
|
const setBlur = (enabled, value) => {
|
|
const blurEffect = enabled ? `blur(${value}px)` : 'none';
|
|
document.documentElement.style.setProperty('--container-blur', blurEffect);
|
|
blurValue.textContent = `${value}px`;
|
|
blurControl.value = value;
|
|
blurToggle.checked = enabled;
|
|
localStorage.setItem('blurEnabled', enabled);
|
|
localStorage.setItem('blurAmount', value);
|
|
blurControl.disabled = !enabled;
|
|
blurValue.style.opacity = enabled ? '1' : '0.5';
|
|
blurControl.style.opacity = enabled ? '1' : '0.5';
|
|
};
|
|
|
|
// Load saved values or set defaults
|
|
const savedTransparency = localStorage.getItem('transparency') || DEFAULT_TRANSPARENCY;
|
|
const savedBlurEnabled = localStorage.getItem('blurEnabled') === 'true';
|
|
const savedBlurAmount = localStorage.getItem('blurAmount') || DEFAULT_BLUR;
|
|
|
|
setTransparency(parseInt(savedTransparency));
|
|
setBlur(savedBlurEnabled, parseInt(savedBlurAmount));
|
|
|
|
// Event listeners
|
|
transparencyControl.addEventListener('input', (e) => {
|
|
setTransparency(parseInt(e.target.value));
|
|
});
|
|
|
|
resetTransparency.addEventListener('click', () => {
|
|
setTransparency(DEFAULT_TRANSPARENCY);
|
|
});
|
|
|
|
blurToggle.addEventListener('change', (e) => {
|
|
const currentValue = parseInt(blurControl.value);
|
|
setBlur(e.target.checked, currentValue);
|
|
});
|
|
|
|
blurControl.addEventListener('input', (e) => {
|
|
if (blurToggle.checked) {
|
|
setBlur(true, parseInt(e.target.value));
|
|
}
|
|
});
|
|
|
|
// Add reset blur handler
|
|
resetBlur.addEventListener('click', () => {
|
|
setBlur(true, DEFAULT_BLUR);
|
|
blurToggle.checked = true;
|
|
});
|
|
}); |