feat: Improve SortableQueueItem component with enhanced click handling and styling

This commit is contained in:
2025-08-16 17:07:18 -05:00
parent 7710bf3cc9
commit 52a00ca899

View File

@@ -56,56 +56,62 @@ function SortableQueueItem({ track, index, onPlay, onRemove, formatDuration }: S
<div <div
ref={setNodeRef} ref={setNodeRef}
style={style} style={style}
className={`group flex items-center p-3 rounded-lg hover:bg-accent/50 cursor-pointer transition-colors ${ className={`group flex items-center p-3 rounded-lg hover:bg-accent/50 transition-colors ${
isDragging ? 'bg-accent' : '' isDragging ? 'bg-accent' : ''
}`} }`}
onClick={onPlay}
> >
{/* Drag Handle */} {/* Drag Handle */}
<div <div
className="mr-3 opacity-0 group-hover:opacity-100 transition-opacity cursor-grab active:cursor-grabbing" className="mr-3 opacity-60 group-hover:opacity-100 transition-opacity cursor-grab active:cursor-grabbing p-1 -m-1 hover:bg-accent rounded"
{...attributes} {...attributes}
{...listeners} {...listeners}
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
onMouseDown={(e) => e.stopPropagation()}
> >
<GripVertical className="w-4 h-4 text-muted-foreground" /> <GripVertical className="w-4 h-4 text-muted-foreground" />
</div> </div>
{/* Album Art with Play Indicator */} {/* Clickable content area for play */}
<div className="w-12 h-12 mr-4 shrink-0 relative"> <div
<Image className="flex items-center flex-1 cursor-pointer"
src={track.coverArt || '/default-user.jpg'} onClick={onPlay}
alt={track.album} >
width={48} {/* Album Art with Play Indicator */}
height={48} <div className="w-12 h-12 mr-4 shrink-0 relative">
className="w-full h-full object-cover rounded-md" <Image
/> src={track.coverArt || '/default-user.jpg'}
<div className="absolute inset-0 bg-black/50 rounded-md opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center"> alt={track.album}
<Play className="w-5 h-5 text-white" /> width={48}
</div> height={48}
</div> className="w-full h-full object-cover rounded-md"
/>
{/* Song Info */} <div className="absolute inset-0 bg-black/50 rounded-md opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center">
<div className="flex-1 min-w-0 mr-4"> <Play className="w-5 h-5 text-white" />
<div className="flex items-center gap-2 mb-1">
<p className="font-semibold truncate">{track.name}</p>
</div>
<div className="flex items-center text-sm text-muted-foreground space-x-4">
<div className="flex items-center gap-1">
<Link
href={`/artist/${track.artistId}`}
className="truncate hover:text-primary hover:underline"
onClick={(e) => e.stopPropagation()}
>
{track.artist}
</Link>
</div> </div>
</div> </div>
</div>
{/* Duration */} {/* Song Info */}
<div className="flex items-center text-sm text-muted-foreground mr-4"> <div className="flex-1 min-w-0 mr-4">
{formatDuration(track.duration)} <div className="flex items-center gap-2 mb-1">
<p className="font-semibold truncate">{track.name}</p>
</div>
<div className="flex items-center text-sm text-muted-foreground space-x-4">
<div className="flex items-center gap-1">
<Link
href={`/artist/${track.artistId}`}
className="truncate hover:text-primary hover:underline"
onClick={(e) => e.stopPropagation()}
>
{track.artist}
</Link>
</div>
</div>
</div>
{/* Duration */}
<div className="flex items-center text-sm text-muted-foreground mr-4">
{formatDuration(track.duration)}
</div>
</div> </div>
{/* Actions */} {/* Actions */}
@@ -130,7 +136,11 @@ const QueuePage: React.FC = () => {
const { queue, currentTrack, removeTrackFromQueue, clearQueue, skipToTrackInQueue, reorderQueue } = useAudioPlayer(); const { queue, currentTrack, removeTrackFromQueue, clearQueue, skipToTrackInQueue, reorderQueue } = useAudioPlayer();
const sensors = useSensors( const sensors = useSensors(
useSensor(PointerSensor), useSensor(PointerSensor, {
activationConstraint: {
distance: 8, // Require 8px of movement before starting drag
},
}),
useSensor(KeyboardSensor, { useSensor(KeyboardSensor, {
coordinateGetter: sortableKeyboardCoordinates, coordinateGetter: sortableKeyboardCoordinates,
}) })