Files
Website-2026/js/gallery.js
T
2026-07-09 01:49:59 +02:00

104 lines
3.0 KiB
JavaScript

const IMAGE_DIR = 'images/';
const MANIFEST = IMAGE_DIR + 'manifest.json';
function parseIndexHtmlList(text) {
// crude parser to extract hrefs from an autoindex HTML listing
const hrefs = [];
const re = /href="([^"]+)"/g;
let m;
while ((m = re.exec(text)) !== null) {
const name = m[1];
if (name.match(/\.(jpe?g|png|webp|gif)$/i)) hrefs.push(name);
}
return hrefs;
}
async function loadImageList() {
// Try manifest first
try {
const r = await fetch(MANIFEST, {cache: 'no-cache'});
if (r.ok) return await r.json();
} catch (e) {
// continue to directory probe
}
try {
const r = await fetch(IMAGE_DIR, {cache: 'no-cache'});
if (r.ok) {
const text = await r.text();
return parseIndexHtmlList(text);
}
} catch (e) {
console.warn('Could not read image directory listing', e);
}
return [];
}
function createThumb(src, idx) {
const img = document.createElement('img');
img.src = src;
img.loading = 'lazy';
img.dataset.index = idx;
img.alt = `Photo ${idx+1}`;
img.addEventListener('click', () => openModal(idx));
return img;
}
let images = [];
let currentIndex = 0;
function openModal(idx) {
currentIndex = idx;
const modal = document.getElementById('gallery-modal');
const mimg = document.getElementById('modal-image');
mimg.src = IMAGE_DIR + images[idx];
modal.classList.remove('hidden');
modal.setAttribute('aria-hidden', 'false');
}
function closeModal() {
const modal = document.getElementById('gallery-modal');
modal.classList.add('hidden');
modal.setAttribute('aria-hidden', 'true');
document.getElementById('modal-image').src = '';
}
function showNext(delta=1) {
if (!images.length) return;
currentIndex = (currentIndex + delta + images.length) % images.length;
document.getElementById('modal-image').src = IMAGE_DIR + images[currentIndex];
}
function setupModalControls() {
document.getElementById('modal-close').addEventListener('click', closeModal);
document.getElementById('modal-prev').addEventListener('click', () => showNext(-1));
document.getElementById('modal-next').addEventListener('click', () => showNext(1));
document.addEventListener('keydown', (e) => {
if (document.getElementById('gallery-modal').classList.contains('hidden')) return;
if (e.key === 'Escape') closeModal();
if (e.key === 'ArrowRight') showNext(1);
if (e.key === 'ArrowLeft') showNext(-1);
});
document.getElementById('gallery-modal').addEventListener('click', (e)=>{
if (e.target.id === 'gallery-modal') closeModal();
});
}
async function initGallery() {
const list = await loadImageList();
images = list;
const container = document.getElementById('gallery-thumbs');
container.innerHTML = '';
if (!images.length) {
container.textContent = 'No images found. Create images/manifest.json or enable directory listing.';
return;
}
images.forEach((name, idx) => {
const thumb = createThumb(IMAGE_DIR + name, idx);
container.appendChild(thumb);
});
setupModalControls();
}
document.addEventListener('DOMContentLoaded', initGallery);