feat: add video playback support in lightbox and photo grid

- Lightbox renders <video> with controls for video assets
- PhotoGrid shows video indicator overlay on video thumbnails
- Skip video preloading in lightbox (streams on demand)
- Add video-related CSS styles
- Update catch-all page to pass video URLs to components
This commit is contained in:
ralksta
2026-05-29 17:05:12 +02:00
parent e9063d3a71
commit 5dffadbe3c
5 changed files with 81 additions and 21 deletions

View File

@@ -67,10 +67,10 @@ export function Lightbox({ assets, currentIndex, onClose, onNext, onPrev }: Ligh
}
}, [showExif, current, fetchExif]);
// Preload adjacent images
// Preload adjacent images (skip videos — they stream on demand)
useEffect(() => {
const preload = (index: number) => {
if (index >= 0 && index < assets.length) {
if (index >= 0 && index < assets.length && assets[index].type !== 'video') {
const img = new Image();
img.src = assets[index].previewUrl;
}
@@ -158,25 +158,41 @@ export function Lightbox({ assets, currentIndex, onClose, onNext, onPrev }: Ligh
</svg>
</button>
{/* Image */}
{/* Image or Video */}
<div
className={styles.imageContainer}
style={{
backgroundColor: current.dominantColor || '#000',
backgroundImage: current.blurDataURL ? `url(${current.blurDataURL})` : undefined,
backgroundImage:
current.type !== 'video' && current.blurDataURL
? `url(${current.blurDataURL})`
: undefined,
backgroundSize: 'cover',
backgroundPosition: 'center',
}}
>
{/* eslint-disable-next-line @next/next/no-img-element */}
<img
className={`${styles.image}${imageLoaded ? ` ${styles.imageLoaded}` : ''}`}
src={current.previewUrl}
alt=""
draggable={false}
onLoad={() => setImageLoaded(true)}
onError={() => console.error(`[Lightbox] Failed to load image: ${current.previewUrl}`)}
/>
{current.type === 'video' && current.videoUrl ? (
// eslint-disable-next-line jsx-a11y/media-has-caption
<video
className={`${styles.image}${imageLoaded ? ` ${styles.imageLoaded}` : ''}`}
src={current.videoUrl}
controls
autoPlay={false}
playsInline
onCanPlay={() => setImageLoaded(true)}
onError={() => console.error(`[Lightbox] Failed to load video: ${current.videoUrl}`)}
/>
) : (
// eslint-disable-next-line @next/next/no-img-element
<img
className={`${styles.image}${imageLoaded ? ` ${styles.imageLoaded}` : ''}`}
src={current.previewUrl}
alt=""
draggable={false}
onLoad={() => setImageLoaded(true)}
onError={() => console.error(`[Lightbox] Failed to load image: ${current.previewUrl}`)}
/>
)}
</div>
{/* Next button */}