diff --git a/client/src/components/video-modal.tsx b/client/src/components/video-modal.tsx index 5298bf9..4bf4150 100644 --- a/client/src/components/video-modal.tsx +++ b/client/src/components/video-modal.tsx @@ -63,6 +63,9 @@ export default function VideoModal({ video, isOpen, onClose }: VideoModalProps) const [isMuted, setIsMuted] = useState(false); const [showControls, setShowControls] = useState(true); const [controlsTimeout, setControlsTimeout] = useState(null); + const [currentTime, setCurrentTime] = useState(0); + const [duration, setDuration] = useState(0); + const [volume, setVolume] = useState(1); useEffect(() => { const handleEscape = (e: KeyboardEvent) => { @@ -245,7 +248,13 @@ export default function VideoModal({ video, isOpen, onClose }: VideoModalProps) videoElement.addEventListener('play', () => setIsPlaying(true)); videoElement.addEventListener('pause', () => setIsPlaying(false)); - videoElement.addEventListener('volumechange', () => setIsMuted(videoElement.muted)); + videoElement.addEventListener('volumechange', () => { + setIsMuted(videoElement.muted); + setVolume(videoElement.volume); + }); + videoElement.addEventListener('timeupdate', () => setCurrentTime(videoElement.currentTime)); + videoElement.addEventListener('loadedmetadata', () => setDuration(videoElement.duration)); + videoElement.addEventListener('durationchange', () => setDuration(videoElement.duration)); } // Cleanup when modal closes @@ -345,6 +354,31 @@ export default function VideoModal({ video, isOpen, onClose }: VideoModalProps) return `${window.location.origin}?video=${video.id}`; }; + const handleProgressClick = (e: React.MouseEvent) => { + if (videoRef.current && duration > 0) { + const rect = e.currentTarget.getBoundingClientRect(); + const clickX = e.clientX - rect.left; + const newTime = (clickX / rect.width) * duration; + videoRef.current.currentTime = newTime; + setCurrentTime(newTime); + } + }; + + const handleVolumeChange = (e: React.ChangeEvent) => { + const newVolume = parseFloat(e.target.value); + if (videoRef.current) { + videoRef.current.volume = newVolume; + setVolume(newVolume); + setIsMuted(newVolume === 0); + } + }; + + const formatTime = (time: number): string => { + const minutes = Math.floor(time / 60); + const seconds = Math.floor(time % 60); + return `${minutes}:${seconds.toString().padStart(2, '0')}`; + }; + const copyToClipboard = async () => { try { await navigator.clipboard.writeText(getShareUrl()); @@ -434,7 +468,21 @@ export default function VideoModal({ video, isOpen, onClose }: VideoModalProps) {/* Bottom Control Bar */} {showControls && ( -
+
+ {/* Progress Bar */} +
+
+
0 ? (currentTime / duration) * 100 : 0}%` }} + /> +
+
+
{/* Play/Pause Button */} +
+ + +
+ + {/* Time Display */} +
+ {formatTime(currentTime)} / {formatTime(duration)} +
{/* Fullscreen Button */}