diff --git a/static/js/app.js b/static/js/app.js index 4b0e154..17409ed 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -212,6 +212,7 @@ let lbBuilt = false; let lbReferrer = null; // URL to return to on close let imgZoomOpen = false; + let imgZoomIdx = -1; function lbOpen(slug, scopedList) { lbList = scopedList || POSTS; @@ -350,8 +351,8 @@ document.addEventListener('keydown', e => { if (lb.dataset.open !== 'true') return; if (e.key === 'Escape') { if (imgZoomOpen) closeImgZoom(); else lbClose(); } - if (e.key === 'ArrowLeft') { e.preventDefault(); goToSlide(lbIdx - 1); } - if (e.key === 'ArrowRight') { e.preventDefault(); goToSlide(lbIdx + 1); } + if (e.key === 'ArrowLeft') { e.preventDefault(); imgZoomOpen ? goToZoomSlide(imgZoomIdx - 1) : goToSlide(lbIdx - 1); } + if (e.key === 'ArrowRight') { e.preventDefault(); imgZoomOpen ? goToZoomSlide(imgZoomIdx + 1) : goToSlide(lbIdx + 1); } }); // Touch swipe @@ -477,6 +478,7 @@ function openImgZoom(src) { if (!imgZoom || !imgZoomImg || !src) return; imgZoomImg.src = src; + imgZoomIdx = lbIdx; imgZoom.dataset.open = 'true'; imgZoomOpen = true; document.body.style.overflow = 'hidden'; @@ -489,6 +491,14 @@ if (!lb || lb.dataset.open !== 'true') document.body.style.overflow = ''; } + function goToZoomSlide(idx) { + if (!lbList.length || !imgZoomImg) return; + imgZoomIdx = Math.max(0, Math.min(idx, lbList.length - 1)); + const p = lbList[imgZoomIdx]; + if (p) imgZoomImg.src = p.card || p.thumb || ''; + goToSlide(imgZoomIdx); + } + // Hero "View full image" button const viewFullBtn = document.getElementById('viewFull'); if (viewFullBtn) { @@ -505,6 +515,16 @@ if (imgZoom) { imgZoom.addEventListener('click', e => { if (e.target === imgZoom) closeImgZoom(); }); document.getElementById('imgZoomClose')?.addEventListener('click', closeImgZoom); + + // Swipe to navigate + let zoomTouchX = null; + imgZoom.addEventListener('touchstart', e => { zoomTouchX = e.touches[0].clientX; }, { passive: true }); + imgZoom.addEventListener('touchend', e => { + if (zoomTouchX === null) return; + const dx = e.changedTouches[0].clientX - zoomTouchX; + if (Math.abs(dx) > 50) dx < 0 ? goToZoomSlide(imgZoomIdx + 1) : goToZoomSlide(imgZoomIdx - 1); + zoomTouchX = null; + }); } // Escape when lightbox is NOT open (standalone zoom)