import React, { useState } from 'react'; import { useAudio } from '../../../context/AudioContext'; import { Card } from '../../ui/card'; import { Button } from '../../ui/button'; import { EmptyState } from '../../ui/empty-state'; import { SaveQueueAsPlaylistModal } from './SaveQueueAsPlaylistModal'; import { createPlaylist, addTrack, } from '../../../features/playlists/services/playlistService'; import { Play, Pause, X, GripVertical, Trash2, Save, ListMusic, } from 'lucide-react'; import { useToast } from '../../../components/feedback/ToastProvider'; export const QueueView: React.FC = () => { const { queue, currentTrack, reorderQueue, removeFromQueue, clearQueue, playTrack, isPlaying, togglePlay, autoplay, toggleAutoplay, } = useAudio(); const { addToast } = useToast(); const [showSaveModal, setShowSaveModal] = useState(false); const [draggedIndex, setDraggedIndex] = useState(null); const [dragOverIndex, setDragOverIndex] = useState(null); const handleDragStart = (e: React.DragEvent, index: number) => { setDraggedIndex(index); e.dataTransfer.effectAllowed = 'move'; // Transparent ghost image const ghost = document.createElement('div'); ghost.style.opacity = '0'; document.body.appendChild(ghost); e.dataTransfer.setDragImage(ghost, 0, 0); setTimeout(() => document.body.removeChild(ghost), 0); }; const handleDragOver = (e: React.DragEvent, index: number) => { e.preventDefault(); setDragOverIndex(index); if (draggedIndex === null || draggedIndex === index) return; reorderQueue(draggedIndex, index); setDraggedIndex(index); }; const handleDragEnd = () => { setDraggedIndex(null); setDragOverIndex(null); }; const handleSavePlaylist = async (name: string, isPublic: boolean) => { const tracksToSave = [ ...(currentTrack ? [currentTrack] : []), ...queue, ]; if (tracksToSave.length === 0) { addToast('Queue is empty', 'error'); throw new Error('Queue is empty'); } const playlist = await createPlaylist({ title: name, description: '', is_public: isPublic, }); for (const track of tracksToSave) { await addTrack(playlist.id, String(track.id)); } addToast(`Queue saved as "${name}"`, 'success'); }; return (

PLAY QUEUE

{queue.length} tracks upcoming

{/* Current Track */} {currentTrack && (

Now Playing

{isPlaying ? ( ) : ( )}
{isPlaying && (
)}

{currentTrack.title}

{currentTrack.artist}

{currentTrack.duration}
)} {/* Up Next */}

Up Next

Autoplay
{queue.length === 0 ? ( } title="Nothing in your queue" description={ autoplay ? 'Autoplay is on — we\u2019ll pick something for you.' : 'Start playing music and add tracks to build your queue.' } size="md" /> ) : ( queue.map((track, i) => (
handleDragStart(e, i)} onDragOver={(e) => handleDragOver(e, i)} onDragEnd={handleDragEnd} className={`flex items-center gap-4 p-4 bg-card rounded-lg border border-transparent hover:border-border transition-all group ${draggedIndex === i ? 'opacity-50 border-primary shadow-lg scale-[1.02] cursor-grabbing' : ''} ${dragOverIndex === i && draggedIndex !== null && draggedIndex !== i ? 'border-t-2 border-t-primary bg-primary/5' : ''}`} >
playTrack(track)} >
{track.title}
{track.artist}
{track.duration}
)) )}
{showSaveModal && ( setShowSaveModal(false)} onSave={handleSavePlaylist} /> )}
); };