Spaces:
Running
Running
| import { useWaveSurfer } from "../hooks/useWaveSurfer"; | |
| interface WaveformPlayerProps { | |
| url: string; | |
| color: string; | |
| height?: number; | |
| instanceId: string; | |
| onDownload?: () => void; | |
| } | |
| function formatTime(seconds: number): string { | |
| const m = Math.floor(seconds / 60); | |
| const s = Math.floor(seconds % 60); | |
| return `${m}:${s.toString().padStart(2, "0")}`; | |
| } | |
| export function WaveformPlayer({ | |
| url, | |
| color, | |
| height = 64, | |
| instanceId, | |
| onDownload, | |
| }: WaveformPlayerProps) { | |
| const { containerRef, isPlaying, isReady, currentTime, duration, togglePlay } = | |
| useWaveSurfer({ url, color, height, instanceId }); | |
| return ( | |
| <div className="flex items-center gap-3 w-full min-w-0"> | |
| {/* Play/Pause button */} | |
| <button | |
| onClick={togglePlay} | |
| disabled={!isReady} | |
| className="flex-shrink-0 w-10 h-10 rounded-full flex items-center justify-center transition-colors disabled:opacity-30" | |
| style={{ backgroundColor: color + "20", color }} | |
| > | |
| {isPlaying ? ( | |
| <svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"> | |
| <rect x="6" y="4" width="4" height="16" rx="1" /> | |
| <rect x="14" y="4" width="4" height="16" rx="1" /> | |
| </svg> | |
| ) : ( | |
| <svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"> | |
| <path d="M8 5.14v14l11-7-11-7z" /> | |
| </svg> | |
| )} | |
| </button> | |
| {/* Waveform */} | |
| <div ref={containerRef} className="flex-grow min-w-0" /> | |
| {/* Time */} | |
| <span className="flex-shrink-0 text-xs text-text-secondary font-mono w-[85px] text-right"> | |
| {isReady ? `${formatTime(currentTime)} / ${formatTime(duration)}` : "--:--"} | |
| </span> | |
| {/* Download button */} | |
| {onDownload && ( | |
| <button | |
| onClick={(e) => { | |
| e.stopPropagation(); | |
| onDownload(); | |
| }} | |
| className="flex-shrink-0 w-8 h-8 rounded-lg flex items-center justify-center text-text-secondary hover:text-text-primary hover:bg-bg-hover transition-colors" | |
| title="Download" | |
| > | |
| <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}> | |
| <path strokeLinecap="round" strokeLinejoin="round" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" /> | |
| </svg> | |
| </button> | |
| )} | |
| </div> | |
| ); | |
| } | |