Inital upload
This commit is contained in:
+103
@@ -0,0 +1,103 @@
|
||||
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);
|
||||
Reference in New Issue
Block a user