'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()}
>
{/* Album Art with Play Indicator */}
{/* Song Info */}
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),
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 */}
{/* Song Info */}
{/* 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;