"use client"; import { Play, Pause, SkipBack, SkipForward, Repeat, Shuffle, Volume2, VolumeX, Download, Disc, PlusCircle, Mic2, Heart, Loader2, ListMusic, MonitorSpeaker, Maximize2 } from 'lucide-react'; import { usePlayer } from "@/context/PlayerContext"; import { useEffect, useRef, useState } from "react"; import TechSpecs from './TechSpecs'; import AddToPlaylistModal from "@/components/AddToPlaylistModal"; import LyricsDetail from './LyricsDetail'; export default function PlayerBar() { const { currentTrack, isPlaying, isBuffering, togglePlay, setBuffering, likedTracks, toggleLike, nextTrack, prevTrack, shuffle, toggleShuffle, repeatMode, toggleRepeat, audioQuality } = usePlayer(); const audioRef = useRef(null); const [progress, setProgress] = useState(0); const [duration, setDuration] = useState(0); const [volume, setVolume] = useState(1); // Modal State const [isAddToPlaylistOpen, setIsAddToPlaylistOpen] = useState(false); const [isLyricsOpen, setIsLyricsOpen] = useState(false); const [isTechSpecsOpen, setIsTechSpecsOpen] = useState(false); const [isFullScreenPlayerOpen, setIsFullScreenPlayerOpen] = useState(false); const [isCoverModalOpen, setIsCoverModalOpen] = useState(false); useEffect(() => { if (currentTrack && audioRef.current && currentTrack.url) { // Prevent reloading if URL hasn't changed const isSameUrl = audioRef.current.src === currentTrack.url || (currentTrack.url.startsWith('/') && audioRef.current.src.endsWith(currentTrack.url)) || (audioRef.current.src.includes(currentTrack.id)); // Fallback for stream IDs if (isSameUrl) return; audioRef.current.src = currentTrack.url; if (isPlaying) { audioRef.current.play().catch(e => console.error("Play error:", e)); } } }, [currentTrack?.url]); useEffect(() => { if (audioRef.current) { if (isPlaying) audioRef.current.play().catch(e => console.error("Play error:", e)); else audioRef.current.pause(); } }, [isPlaying]); // Volume Effect useEffect(() => { if (audioRef.current) { audioRef.current.volume = volume; } }, [volume]); const handleTimeUpdate = () => { if (audioRef.current) { setProgress(audioRef.current.currentTime); if (!isNaN(audioRef.current.duration)) { setDuration(audioRef.current.duration); } } }; const handleSeek = (e: React.ChangeEvent) => { const time = parseFloat(e.target.value); if (audioRef.current) { audioRef.current.currentTime = time; setProgress(time); } }; const handleVolume = (e: React.ChangeEvent) => { const vol = parseFloat(e.target.value); setVolume(vol); }; const handleDownload = () => { if (!currentTrack) return; const apiUrl = process.env.NEXT_PUBLIC_API_URL || ''; const url = `${apiUrl}/api/download?id=${currentTrack.id}&title=${encodeURIComponent(currentTrack.title)}`; window.open(url, '_blank'); }; const formatTime = (time: number) => { if (isNaN(time)) return "0:00"; const minutes = Math.floor(time / 60); const seconds = Math.floor(time % 60); return `${minutes}:${seconds.toString().padStart(2, '0')}`; }; return ( ); }