feat: Improve SortableQueueItem component with enhanced click handling and styling
This commit is contained in:
@@ -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,
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user