feat(DirectorySlideshow): enhance slideshow controls with persistent pause state and improved index handling
This commit is contained in:
parent
096f13d926
commit
b8d3041035
|
|
@ -10,7 +10,7 @@ interface Props {
|
||||||
export default function DirectorySlideshow({ path }: Props) {
|
export default function DirectorySlideshow({ path }: Props) {
|
||||||
const [images, setImages] = useState<EntryInfo[]>([]);
|
const [images, setImages] = useState<EntryInfo[]>([]);
|
||||||
const [idx, setIdx] = useState(0);
|
const [idx, setIdx] = useState(0);
|
||||||
const [paused, setPaused] = useState(false);
|
const [paused, setPaused] = useState(() => localStorage.getItem('slideshow.paused') === '1');
|
||||||
const [touched, setTouched] = useState(false);
|
const [touched, setTouched] = useState(false);
|
||||||
const touchTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
|
const touchTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
|
||||||
|
|
||||||
|
|
@ -24,7 +24,8 @@ export default function DirectorySlideshow({ path }: Props) {
|
||||||
return IMAGE_EXTS.has(ext);
|
return IMAGE_EXTS.has(ext);
|
||||||
});
|
});
|
||||||
setImages(imgs);
|
setImages(imgs);
|
||||||
setIdx(0);
|
const saved = parseInt(localStorage.getItem(`slideshow.idx:${path}`) ?? '0', 10);
|
||||||
|
setIdx(imgs.length > 0 ? Math.min(saved, imgs.length - 1) : 0);
|
||||||
})
|
})
|
||||||
.catch(() => setImages([]));
|
.catch(() => setImages([]));
|
||||||
}, [path]);
|
}, [path]);
|
||||||
|
|
@ -35,6 +36,11 @@ export default function DirectorySlideshow({ path }: Props) {
|
||||||
return () => clearInterval(t);
|
return () => clearInterval(t);
|
||||||
}, [images.length, paused]);
|
}, [images.length, paused]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (images.length === 0) return;
|
||||||
|
localStorage.setItem(`slideshow.idx:${path}`, String(idx));
|
||||||
|
}, [idx, path, images.length]);
|
||||||
|
|
||||||
useEffect(() => () => clearTimeout(touchTimer.current), []);
|
useEffect(() => () => clearTimeout(touchTimer.current), []);
|
||||||
|
|
||||||
if (images.length === 0) return null;
|
if (images.length === 0) return null;
|
||||||
|
|
@ -73,15 +79,18 @@ export default function DirectorySlideshow({ path }: Props) {
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Dots + pause */}
|
{/* Pause / play — centered */}
|
||||||
<div className={`absolute bottom-0 left-0 right-0 flex items-center justify-center gap-2 py-1.5 transition-opacity duration-200 ${controlsVisible}`}>
|
<div className={`absolute inset-0 flex items-center justify-center pointer-events-none transition-opacity duration-200 ${controlsVisible}`}>
|
||||||
<button
|
<button
|
||||||
onClick={() => setPaused(p => !p)}
|
onClick={() => setPaused(p => { const next = !p; localStorage.setItem('slideshow.paused', next ? '1' : '0'); return next; })}
|
||||||
className="p-0.5 rounded-full bg-black/50 text-white hover:bg-black/70"
|
className="pointer-events-auto p-3 rounded-full bg-black/50 text-white hover:bg-black/70"
|
||||||
>
|
>
|
||||||
{paused ? <Play className="w-3 h-3" /> : <Pause className="w-3 h-3" />}
|
{paused ? <Play className="w-7 h-7" /> : <Pause className="w-7 h-7" />}
|
||||||
</button>
|
</button>
|
||||||
<div className="flex gap-1.5">
|
</div>
|
||||||
|
|
||||||
|
{/* Dots */}
|
||||||
|
<div className={`absolute bottom-0 left-0 right-0 flex justify-center gap-1.5 py-1.5 transition-opacity duration-200 ${controlsVisible}`}>
|
||||||
{images.map((_, i) => (
|
{images.map((_, i) => (
|
||||||
<button
|
<button
|
||||||
key={i}
|
key={i}
|
||||||
|
|
@ -90,7 +99,6 @@ export default function DirectorySlideshow({ path }: Props) {
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user