Spaces:
Running
Running
| import React, { useState, useEffect } from 'react'; | |
| import { Button } from '@/components/ui/button'; | |
| import { Play, Pause, FastForward, Rewind, ChevronsRight, ChevronsLeft } from 'lucide-react'; | |
| import { Slider } from '@/components/ui/slider'; | |
| interface PlaybackControlsProps { | |
| duration: number; // in seconds | |
| } | |
| const PlaybackControls: React.FC<PlaybackControlsProps> = ({ duration }) => { | |
| const [isPlaying, setIsPlaying] = useState(false); | |
| const [currentTime, setCurrentTime] = useState(0); | |
| const [playbackSpeed, setPlaybackSpeed] = useState(1); | |
| useEffect(() => { | |
| // Reset time when episode changes (duration changes) | |
| setCurrentTime(0); | |
| setIsPlaying(false); | |
| }, [duration]); | |
| // This is a mock playback timer. | |
| useEffect(() => { | |
| let interval: NodeJS.Timeout; | |
| if (isPlaying && currentTime < duration) { | |
| interval = setInterval(() => { | |
| setCurrentTime(prev => Math.min(prev + (1 * playbackSpeed), duration)); | |
| }, 1000); | |
| } | |
| if (currentTime >= duration) { | |
| setIsPlaying(false); | |
| } | |
| return () => clearInterval(interval); | |
| }, [isPlaying, duration, playbackSpeed, currentTime]); | |
| const formatTime = (time: number) => { | |
| const minutes = Math.floor(time / 60); | |
| const seconds = Math.floor(time % 60); | |
| return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; | |
| }; | |
| const speedOptions = [0.5, 1, 1.5, 2]; | |
| return ( | |
| <div className="space-y-3"> | |
| <div className="flex items-center gap-2"> | |
| <Slider | |
| value={[currentTime]} | |
| max={duration} | |
| step={1} | |
| onValueChange={(value) => setCurrentTime(value[0])} | |
| className="w-full" | |
| /> | |
| </div> | |
| <div className="flex justify-between items-center text-xs text-gray-400"> | |
| <span>{formatTime(currentTime)}</span> | |
| <span>{formatTime(duration)}</span> | |
| </div> | |
| <div className="flex items-center justify-center gap-2"> | |
| <Button variant="ghost" size="icon" className="text-gray-300 hover:text-white hover:bg-gray-700"> | |
| <ChevronsLeft /> | |
| </Button> | |
| <Button onClick={() => setCurrentTime(t => Math.max(0, t - 5))} variant="ghost" size="icon" className="text-gray-300 hover:text-white hover:bg-gray-700"> | |
| <Rewind /> | |
| </Button> | |
| <Button onClick={() => setIsPlaying(!isPlaying)} variant="ghost" size="icon" className="h-12 w-12 text-gray-300 hover:text-white hover:bg-gray-700"> | |
| {isPlaying ? <Pause className="h-6 w-6" /> : <Play className="h-6 w-6" />} | |
| </Button> | |
| <Button onClick={() => setCurrentTime(t => Math.min(duration, t + 5))} variant="ghost" size="icon" className="text-gray-300 hover:text-white hover:bg-gray-700"> | |
| <FastForward /> | |
| </Button> | |
| <Button variant="ghost" size="icon" className="text-gray-300 hover:text-white hover:bg-gray-700"> | |
| <ChevronsRight /> | |
| </Button> | |
| </div> | |
| <div className="flex justify-center items-center gap-2 pt-2"> | |
| <span className="text-sm text-gray-400">Speed:</span> | |
| {speedOptions.map(speed => ( | |
| <Button | |
| key={speed} | |
| variant={playbackSpeed === speed ? 'secondary' : 'ghost'} | |
| size="sm" | |
| onClick={() => setPlaybackSpeed(speed)} | |
| className="text-xs" | |
| > | |
| {speed}x | |
| </Button> | |
| ))} | |
| </div> | |
| </div> | |
| ); | |
| }; | |
| export default PlaybackControls; | |