import { useEffect, useRef, useState } from 'react'; import { ChevronLeft, ChevronRight, Pause, Play } from 'lucide-react'; import { listDirectory, getWebDAVBaseUrl, type EntryInfo } from '../webdav'; import { IMAGE_EXTS } from './MediaEntry'; interface Props { path: string; } export default function DirectorySlideshow({ path }: Props) { const [images, setImages] = useState([]); const [idx, setIdx] = useState(0); const [paused, setPaused] = useState(() => localStorage.getItem('slideshow.paused') === '1'); const [touched, setTouched] = useState(false); const touchTimer = useRef | undefined>(undefined); useEffect(() => { if (!path) { setImages([]); return; } listDirectory(path) .then(entries => { const imgs = entries.filter(e => { if (e.type !== 'file') return false; const ext = e.name.split('.').pop()?.toLowerCase() ?? ''; return IMAGE_EXTS.has(ext); }); setImages(imgs); const saved = parseInt(localStorage.getItem(`slideshow.idx:${path}`) ?? '0', 10); setIdx(imgs.length > 0 ? Math.min(saved, imgs.length - 1) : 0); }) .catch(() => setImages([])); }, [path]); useEffect(() => { if (images.length <= 1 || paused) return; const t = setInterval(() => setIdx(i => (i + 1) % images.length), 4000); return () => clearInterval(t); }, [images.length, paused]); useEffect(() => { if (images.length === 0) return; localStorage.setItem(`slideshow.idx:${path}`, String(idx)); }, [idx, path, images.length]); useEffect(() => () => clearTimeout(touchTimer.current), []); if (images.length === 0) return null; const current = images[idx]; const prev = () => setIdx(i => (i - 1 + images.length) % images.length); const next = () => setIdx(i => (i + 1) % images.length); const handleTouch = () => { setTouched(true); clearTimeout(touchTimer.current); touchTimer.current = setTimeout(() => setTouched(false), 3000); }; const controlsVisible = touched ? 'opacity-100' : 'opacity-0 group-hover:opacity-100'; return (
{current.name} {images.length > 1 && ( <> {/* Prev / next */}
{/* Pause / play — centered */}
{/* Dots */}
{images.map((_, i) => (
)}
); }