feat: multiple layouts

This commit is contained in:
2025-11-15 13:25:00 +01:00
parent 0a986f4293
commit 3f0fbed557
3 changed files with 321 additions and 1 deletions

View File

@@ -13,11 +13,14 @@ const searchToggle = document.getElementById('searchToggle');
const searchWrapper = document.getElementById('searchWrapper');
const addLinkToggle = document.getElementById('addLinkToggle');
const addLinkWrapper = document.getElementById('addLinkWrapper');
const layoutToggle = document.getElementById('layoutToggle');
const layoutDropdown = document.getElementById('layoutDropdown');
// State
let allLinks = [];
let searchTimeout = null;
let showArchived = false;
let currentLayout = 'masonry'; // Default layout
// Initialize app
document.addEventListener('DOMContentLoaded', () => {
@@ -26,6 +29,8 @@ document.addEventListener('DOMContentLoaded', () => {
setupScrollToTop();
setupMobileSearch();
setupMobileAddLink();
setupLayoutToggle();
applyLayout(currentLayout);
});
// Event listeners
@@ -109,6 +114,48 @@ function setupMobileAddLink() {
});
}
// Setup layout toggle
function setupLayoutToggle() {
if (!layoutToggle || !layoutDropdown) return;
// Toggle dropdown on button click
layoutToggle.addEventListener('click', (e) => {
e.stopPropagation();
layoutDropdown.classList.toggle('show');
layoutToggle.classList.toggle('active');
});
// Close dropdown when clicking outside
document.addEventListener('click', (e) => {
if (!layoutToggle.contains(e.target) && !layoutDropdown.contains(e.target)) {
layoutDropdown.classList.remove('show');
layoutToggle.classList.remove('active');
}
});
// Handle layout option clicks
layoutDropdown.querySelectorAll('.layout-option').forEach(option => {
option.addEventListener('click', () => {
const layout = option.dataset.layout;
applyLayout(layout);
layoutDropdown.classList.remove('show');
layoutToggle.classList.remove('active');
});
});
}
// Apply layout
function applyLayout(layout) {
currentLayout = layout;
linksContainer.className = 'links-container';
linksContainer.classList.add(`layout-${layout}`);
// Update active state in dropdown
layoutDropdown.querySelectorAll('.layout-option').forEach(option => {
option.classList.toggle('active', option.dataset.layout === layout);
});
}
// Setup scroll to top button
function setupScrollToTop() {
// Show/hide button based on scroll position
@@ -267,6 +314,7 @@ function displayLinks(links) {
}
linksContainer.innerHTML = links.map(link => createLinkCard(link)).join('');
applyLayout(currentLayout);
// Add delete event listeners
document.querySelectorAll('.delete-btn').forEach(btn => {
@@ -301,7 +349,9 @@ function createLinkCard(link) {
return `
<div class="link-card" data-id="${link.id}">
<div class="link-image">
${imageHtml}
<a href="${escapeHtml(link.url)}" target="_blank" rel="noopener noreferrer" class="link-image-link">
${imageHtml}
</a>
</div>
<div class="link-content">
<h3 class="link-title">${escapeHtml(link.title)}</h3>