ClickOnPostV1

This commit is contained in:
2026-01-29 13:25:20 +11:00
parent f67099f5b0
commit 36ff34c893
3 changed files with 151 additions and 7 deletions

View File

@@ -256,6 +256,20 @@
</div>
</div>
</div>
<!-- Lightbox View -->
<div id="lightbox-view" class="hidden">
<button id="lightbox-close" class="icon-btn-lg">
<svg viewBox="0 0 24 24" width="32" height="32" stroke="white" stroke-width="2" fill="none">
<line x1="18" y1="6" x2="6" y2="18"></line>
<line x1="6" y1="6" x2="18" y2="18"></line>
</svg>
</button>
<div class="lightbox-carousel">
<!-- Dynamic Slides injected here -->
</div>
<div class="media-counter" style="bottom: 40px; top: auto;"></div> <!-- Re-use styling -->
</div>
<script src="script.js"></script>
</body>

View File

@@ -91,8 +91,64 @@ document.addEventListener('DOMContentLoaded', () => {
const navPostBtn = document.querySelector('.nav-btn:nth-child(2)');
const navHomeBtn = document.querySelector('.nav-btn:first-child');
// Lightbox Elements
const lightboxView = document.getElementById('lightbox-view');
const lightboxClose = document.getElementById('lightbox-close');
const lightboxCarousel = document.querySelector('.lightbox-carousel');
// We check for counter inside helper, as it might be common class
let isLoginMode = true;
// --- LIGHTBOX LOGIC ---
function openLightbox(media, startIndex) {
if (!lightboxView || !lightboxCarousel) return;
lightboxCarousel.innerHTML = '';
media.forEach((item) => {
const slide = document.createElement('div');
slide.className = 'lightbox-slide';
if (item.type === 'video') {
slide.innerHTML = `<video src="${item.src}" controls playsinline></video>`;
} else {
slide.innerHTML = `<img src="${item.src}">`;
}
lightboxCarousel.appendChild(slide);
});
lightboxView.classList.remove('hidden');
lightboxView.classList.add('fade-in');
// Scroll to index
const width = window.innerWidth;
// Need brief timeout for layout to stabilise
setTimeout(() => {
lightboxCarousel.scrollLeft = width * startIndex;
}, 10);
const lightboxCounter = lightboxView.querySelector('.media-counter');
if (lightboxCounter) {
lightboxCounter.innerText = `${startIndex + 1}/${media.length}`;
lightboxCounter.style.display = media.length > 1 ? 'block' : 'none';
}
// Attach Interactions
enableDragScroll(lightboxCarousel);
lightboxCarousel.onscroll = () => {
const index = Math.round(lightboxCarousel.scrollLeft / window.innerWidth);
if (lightboxCounter) lightboxCounter.innerText = `${index + 1}/${media.length}`;
};
document.body.style.overflow = 'hidden';
}
if (lightboxClose) {
lightboxClose.addEventListener('click', () => {
if (lightboxView) lightboxView.classList.add('hidden');
if (lightboxCarousel) lightboxCarousel.innerHTML = '';
document.body.style.overflow = '';
});
}
// --- AUTH LOGIC ---
if (toggleLink) {
toggleLink.addEventListener('click', (e) => {
@@ -214,7 +270,7 @@ document.addEventListener('DOMContentLoaded', () => {
for (const post of postsToRender) {
if (!isPostDeleted(post.id) && !document.querySelector(`[data-post-id="${post.id}"]`)) {
let mediaItems = post.media;
// Backwards Compatibility
// Backwards Compatibility implementation
if (!mediaItems && post.imageSrc) {
mediaItems = [{ type: 'image', src: post.imageSrc }];
}
@@ -293,12 +349,12 @@ document.addEventListener('DOMContentLoaded', () => {
media.forEach((item, index) => {
if (item.type === 'video') {
slidesHTML += `
<div class="media-slide">
<div class="media-slide" data-index="${index}">
<video src="${item.src}" controls playsinline loop></video>
</div>`;
} else {
slidesHTML += `
<div class="media-slide">
<div class="media-slide" data-index="${index}">
<img src="${item.src}" alt="Post Media ${index + 1}">
</div>`;
}
@@ -353,10 +409,19 @@ document.addEventListener('DOMContentLoaded', () => {
}
else feedContainer.appendChild(article);
// Attach Drag-to-Scroll for Desktop
if (media.length > 1) {
const carousel = article.querySelector('.media-carousel');
if (carousel) enableDragScroll(carousel);
// Attach Drag-to-Scroll & Lightbox Click
const carousel = article.querySelector('.media-carousel');
if (carousel) {
if (media.length > 1) enableDragScroll(carousel);
// Open Lightbox on Click
carousel.addEventListener('click', (e) => {
const slide = e.target.closest('.media-slide');
if (slide && !e.target.tagName.match(/VIDEO|BUTTON/)) {
const index = parseInt(slide.getAttribute('data-index') || '0');
openLightbox(media, index);
}
});
}
}

View File

@@ -887,3 +887,68 @@ p {
backdrop-filter: blur(4px);
}
/* --- LIGHTBOX STYLES --- */
#lightbox-view {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: #000;
z-index: 9999;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
#lightbox-close {
position: absolute;
top: 20px;
right: 20px;
z-index: 100;
background: rgba(0,0,0,0.5);
border-radius: 50%;
padding: 10px;
cursor: pointer;
border: none;
color: white;
}
.lightbox-carousel {
width: 100%;
height: 100%;
display: flex;
overflow-x: auto;
scroll-snap-type: x mandatory;
scrollbar-width: none;
align-items: center;
}
.lightbox-carousel::-webkit-scrollbar {
display: none;
}
.lightbox-slide {
min-width: 100vw;
height: 100vh;
scroll-snap-align: center;
display: flex;
justify-content: center;
align-items: center;
}
.lightbox-slide img,
.lightbox-slide video {
max-width: 100%;
max-height: 100%;
object-fit: contain;
}
/* Fix Specificity Conflict */
#lightbox-view.hidden {
display: none !important;
}