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