'use client'; import React from 'react'; import Image from 'next/image'; import Link from 'next/link'; import { useAudioPlayer, Track } from '@/app/components/AudioPlayerContext'; import { Button } from '@/components/ui/button'; import { Separator } from '@/components/ui/separator'; import { ScrollArea } from '@/components/ui/scroll-area'; import { Play, X, Disc, Trash2, SkipForward, GripVertical } from 'lucide-react'; import { DndContext, closestCenter, KeyboardSensor, PointerSensor, useSensor, useSensors, DragEndEvent, } from '@dnd-kit/core'; import { arrayMove, SortableContext, sortableKeyboardCoordinates, verticalListSortingStrategy, useSortable, } from '@dnd-kit/sortable'; import { CSS, } from '@dnd-kit/utilities'; interface SortableQueueItemProps { track: Track; index: number; onPlay: () => void; onRemove: () => void; formatDuration: (seconds: number) => string; } function SortableQueueItem({ track, index, onPlay, onRemove, formatDuration }: SortableQueueItemProps) { const { attributes, listeners, setNodeRef, transform, transition, isDragging, } = useSortable({ id: `${track.id}-${index}` }); const style = { transform: CSS.Transform.toString(transform), transition, opacity: isDragging ? 0.5 : 1, }; return (
{/* Drag Handle */}
e.stopPropagation()} onMouseDown={(e) => e.stopPropagation()} >
{/* Clickable content area for play */}
{/* Album Art with Play Indicator */}
{track.album}
{/* Song Info */}

{track.name}

e.stopPropagation()} > {track.artist}
{/* Duration */}
{formatDuration(track.duration)}
{/* Actions */}
); } const QueuePage: React.FC = () => { const { queue, currentTrack, removeTrackFromQueue, clearQueue, skipToTrackInQueue, reorderQueue } = useAudioPlayer(); const sensors = useSensors( useSensor(PointerSensor, { activationConstraint: { distance: 8, // Require 8px of movement before starting drag }, }), useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates, }) ); const handleDragEnd = (event: DragEndEvent) => { const { active, over } = event; if (over && active.id !== over.id) { const oldIndex = queue.findIndex((track, index) => `${track.id}-${index}` === active.id); const newIndex = queue.findIndex((track, index) => `${track.id}-${index}` === over.id); if (oldIndex !== -1 && newIndex !== -1) { reorderQueue(oldIndex, newIndex); } } }; const formatDuration = (seconds: number): string => { const minutes = Math.floor(seconds / 60); const remainingSeconds = seconds % 60; return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`; }; return (
{/* Header */}

Queue

{currentTrack ? `Now playing • ${queue.length} songs up next` : `${queue.length} songs in queue`}

{/* Currently Playing */} {currentTrack && (

Now Playing

{/* Album Art */}
{currentTrack.album}
{/* Song Info */}

{currentTrack.name}

{currentTrack.artist}
{/* Duration */}
{formatDuration(currentTrack.duration)}
)} {/* Queue */}

Up Next

{queue.length > 0 && (

{queue.length} song{queue.length !== 1 ? 's' : ''}

)}
{queue.length === 0 ? (

No songs in queue

Add songs to your queue to see them here

) : ( `${track.id}-${index}`)} strategy={verticalListSortingStrategy} >
{queue.map((track, index) => ( skipToTrackInQueue(index)} onRemove={() => removeTrackFromQueue(index)} formatDuration={formatDuration} /> ))}
)}
); }; export default QueuePage;