'use client'; import * as React from 'react'; import { Play, Pause, Square, SkipBack, Volume2, VolumeX } from 'lucide-react'; import { Button } from '@/components/ui/Button'; import { Slider } from '@/components/ui/Slider'; import { cn } from '@/lib/utils/cn'; export interface PlaybackControlsProps { isPlaying: boolean; isPaused: boolean; currentTime: number; duration: number; volume: number; onPlay: () => void; onPause: () => void; onStop: () => void; onSeek: (time: number, autoPlay?: boolean) => void; onVolumeChange: (volume: number) => void; disabled?: boolean; className?: string; currentTimeFormatted?: string; durationFormatted?: string; } export function PlaybackControls({ isPlaying, isPaused, currentTime, duration, volume, onPlay, onPause, onStop, onSeek, onVolumeChange, disabled = false, className, currentTimeFormatted, durationFormatted, }: PlaybackControlsProps) { const [isMuted, setIsMuted] = React.useState(false); const [previousVolume, setPreviousVolume] = React.useState(volume); const handlePlayPause = () => { if (isPlaying) { onPause(); } else { onPlay(); } }; const handleMuteToggle = () => { if (isMuted) { onVolumeChange(previousVolume); setIsMuted(false); } else { setPreviousVolume(volume); onVolumeChange(0); setIsMuted(true); } }; const handleVolumeChange = (newVolume: number) => { onVolumeChange(newVolume); if (newVolume === 0) { setIsMuted(true); } else { setIsMuted(false); } }; const progress = duration > 0 ? (currentTime / duration) * 100 : 0; return (
{/* Timeline Slider */}
onSeek(parseFloat(e.target.value), false)} onMouseUp={(e) => onSeek(parseFloat((e.target as HTMLInputElement).value), true)} onTouchEnd={(e) => onSeek(parseFloat((e.target as HTMLInputElement).value), true)} disabled={disabled || duration === 0} className={cn( 'w-full h-2 bg-secondary rounded-lg appearance-none cursor-pointer', 'focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2', 'disabled:opacity-50 disabled:cursor-not-allowed', '[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4', '[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-primary', '[&::-webkit-slider-thumb]:cursor-pointer [&::-webkit-slider-thumb]:transition-colors', '[&::-webkit-slider-thumb]:hover:bg-primary/90', '[&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:h-4 [&::-moz-range-thumb]:rounded-full', '[&::-moz-range-thumb]:bg-primary [&::-moz-range-thumb]:border-0 [&::-moz-range-thumb]:cursor-pointer' )} style={{ background: `linear-gradient(to right, var(--color-primary) ${progress}%, var(--color-secondary) ${progress}%)`, }} />
{currentTimeFormatted || '00:00'} {durationFormatted || '00:00'}
{/* Transport Controls */}
{/* Volume Control */}
); }