feat: replace DropZone with EndDropArea for improved sound insertion in PlaylistEditPage

This commit is contained in:
JSC
2025-08-11 09:39:50 +02:00
parent 490221ffdd
commit 5182ed36c3

View File

@@ -249,26 +249,18 @@ function AvailableSound({ sound }: AvailableSoundProps) {
)
}
// Drop zone component for inserting sounds at specific positions
interface DropZoneProps {
index: number
isActive: boolean
}
function DropZone({ index, isActive }: DropZoneProps) {
const { isOver, setNodeRef } = useDroppable({
id: `drop-zone-${index}`,
data: { type: 'dropzone', index }
// Simple drop area for the end of the playlist
function EndDropArea() {
const { setNodeRef } = useDroppable({
id: 'playlist-end',
data: { type: 'playlist-end' }
})
return (
<div
ref={setNodeRef}
className={`h-2 transition-colors ${
isActive || isOver
? 'bg-primary/30 border-2 border-dashed border-primary'
: 'transparent'
}`}
className="h-8 w-full" // Invisible drop area
/>
)
}
@@ -543,7 +535,7 @@ export function PlaylistEditPage() {
if (soundToAddBack) {
setAvailableSounds(prev => [...prev, soundToAddBack].sort((a, b) => a.name.localeCompare(b.name)))
}
} catch (err) {
} catch {
// If we can't fetch the sound data, just refresh the available sounds
await fetchAvailableSounds()
}
@@ -589,7 +581,7 @@ export function PlaylistEditPage() {
const overId = over.id as string
// Handle adding sound from available list to playlist
if (activeId.startsWith('available-sound-') && (overId.startsWith('playlist-sound-') || overId.startsWith('drop-zone-'))) {
if (activeId.startsWith('available-sound-') && (overId.startsWith('playlist-sound-') || overId === 'playlist-end')) {
const soundId = parseInt(activeId.replace('available-sound-', ''), 10)
let position = sounds.length // Default to end
@@ -598,8 +590,8 @@ export function PlaylistEditPage() {
const targetSoundId = parseInt(overId.replace('playlist-sound-', ''), 10)
const targetIndex = sounds.findIndex(s => s.id === targetSoundId)
position = targetIndex
} else if (overId.startsWith('drop-zone-')) {
position = parseInt(overId.replace('drop-zone-', ''), 10)
} else if (overId === 'playlist-end') {
position = sounds.length
}
try {
@@ -670,9 +662,8 @@ export function PlaylistEditPage() {
const targetSoundId = parseInt(overId.replace('playlist-sound-', ''), 10)
const targetIndex = sounds.findIndex(s => s.id === targetSoundId)
setDropPosition(targetIndex)
} else if (overId.startsWith('drop-zone-')) {
const position = parseInt(overId.replace('drop-zone-', ''), 10)
setDropPosition(position)
} else if (overId === 'playlist-end') {
setDropPosition(sounds.length)
} else {
setDropPosition(null)
}
@@ -970,8 +961,7 @@ export function PlaylistEditPage() {
items={sounds.map(sound => `playlist-sound-${sound.id}`)}
strategy={verticalListSortingStrategy}
>
<div className="space-y-1">
<DropZone index={0} isActive={draggedItem?.startsWith('available-sound-') || false} />
<div className="space-y-2">
{sounds.map((sound, index) => {
const adjustedIndex = dropPosition !== null && dropPosition <= index ? index + 1 : index
return (
@@ -985,7 +975,6 @@ export function PlaylistEditPage() {
index={adjustedIndex}
onRemoveSound={handleRemoveSound}
/>
<DropZone index={index + 1} isActive={draggedItem?.startsWith('available-sound-') || false} />
</div>
)
})}
@@ -993,6 +982,8 @@ export function PlaylistEditPage() {
{dropPosition === sounds.length && draggedSound && draggedItem?.startsWith('available-sound-') && (
<InlinePreview sound={draggedSound} position={dropPosition} />
)}
{/* Invisible drop area at the end */}
<EndDropArea />
</div>
</SortableContext>
</div>