diff --git a/frontend/src/components/Media/MediaView.tsx b/frontend/src/components/Media/MediaView.tsx index 4a0a79cf5..812de4b94 100644 --- a/frontend/src/components/Media/MediaView.tsx +++ b/frontend/src/components/Media/MediaView.tsx @@ -94,7 +94,7 @@ export function MediaView({ }, [dispatch, resetViewerState]); // Slideshow functionality - const { isSlideshowActive, toggleSlideshow } = useSlideshow( + const { isSlideshowActive, toggleSlideshow, duration, setDuration } = useSlideshow( totalImages, handleNextImage, handleLoopToStart, @@ -175,15 +175,17 @@ export function MediaView({
{/* Controls */} {/* Main viewer area */} diff --git a/frontend/src/components/Media/MediaViewControls.tsx b/frontend/src/components/Media/MediaViewControls.tsx index 8fe88b62e..77ce16d87 100644 --- a/frontend/src/components/Media/MediaViewControls.tsx +++ b/frontend/src/components/Media/MediaViewControls.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState } from 'react'; import { Info, Heart, Play, Pause, X, Folder } from 'lucide-react'; interface MediaViewControlsProps { @@ -11,8 +11,13 @@ interface MediaViewControlsProps { onToggleSlideshow: () => void; onClose: () => void; type?: string; + duration: number; + onDurationChange: (duration: number) => void; } +// snap points in ms, mapped to a 0-2 slider scale +const DURATION_STEPS = [2000, 5000, 10000]; + /** Control buttons for the full-screen media viewer. */ export const MediaViewControls: React.FC = ({ showInfo, @@ -24,7 +29,20 @@ export const MediaViewControls: React.FC = ({ onToggleSlideshow, onClose, type = 'image', + duration, + onDurationChange, }) => { + const [showSettings, setShowSettings] = useState(false); + + // convert current duration (ms) to a step index (0,1,2) for the slider + const currentStepIndex = DURATION_STEPS.indexOf(duration); + const sliderValue = currentStepIndex === -1 ? 0 : currentStepIndex; + + const handleSliderChange = (e: React.ChangeEvent) => { + const stepIndex = Number(e.target.value); + onDurationChange(DURATION_STEPS[stepIndex]); + }; + return (
- - {type === 'image' && ( - + + {showSettings && ( +
+
+
+ 2s + 10s +
+ +
+ {DURATION_STEPS[sliderValue] / 1000}s per image +
+
+
)} - - {isSlideshowActive ? 'Pause' : 'Slideshow'} - - +
)}
); -}; +}; \ No newline at end of file diff --git a/frontend/src/hooks/useSlideshow.ts b/frontend/src/hooks/useSlideshow.ts index 5dd31512b..865156516 100644 --- a/frontend/src/hooks/useSlideshow.ts +++ b/frontend/src/hooks/useSlideshow.ts @@ -7,13 +7,12 @@ export const useSlideshow = ( currentIndex?: number, ) => { const [isSlideshowActive, setIsSlideshowActive] = useState(false); + const [duration, setDuration] = useState(2000); // default 2s useEffect(() => { let slideshowInterval: NodeJS.Timeout | null = null; - if (isSlideshowActive && totalImages > 1) { slideshowInterval = setInterval(() => { - // Loop back to first image when at the end if ( currentIndex !== undefined && onLoopToStart && @@ -23,9 +22,8 @@ export const useSlideshow = ( } else { onNextImage(); } - }, 3000); + }, duration); // <-- was 3000, now uses the duration state } - return () => { if (slideshowInterval) { clearInterval(slideshowInterval); @@ -37,6 +35,7 @@ export const useSlideshow = ( onNextImage, onLoopToStart, currentIndex, + duration, // <-- added, so timer restarts if duration changes ]); const toggleSlideshow = useCallback(() => { @@ -46,5 +45,7 @@ export const useSlideshow = ( return { isSlideshowActive, toggleSlideshow, + duration, // <-- exposing current duration + setDuration, // <-- exposing the setter so other files can change it }; -}; +}; \ No newline at end of file