diff --git a/src/pages/PlaylistEditPage.tsx b/src/pages/PlaylistEditPage.tsx index 2e68326..9a6618d 100644 --- a/src/pages/PlaylistEditPage.tsx +++ b/src/pages/PlaylistEditPage.tsx @@ -9,6 +9,7 @@ import { PointerSensor, useSensor, useSensors, + DragOverlay, } from '@dnd-kit/core' import { SortableContext, @@ -168,42 +169,33 @@ function SimpleSortableRow({ sound, index, onRemoveSound }: SimpleSortableRowPro
-
-
-
-
-
-
-
-
- - - {index + 1} - - - - -
-
- {sound.name} -
+ + {index + 1} + + + + +
+
+ {sound.name}
) @@ -212,9 +204,10 @@ function SimpleSortableRow({ sound, index, onRemoveSound }: SimpleSortableRowPro // Available sound component for dragging interface AvailableSoundProps { sound: Sound + onAddToPlaylist: (soundId: number) => void } -function AvailableSound({ sound }: AvailableSoundProps) { +function AvailableSound({ sound, onAddToPlaylist }: AvailableSoundProps) { const { attributes, listeners, @@ -234,7 +227,7 @@ function AvailableSound({ sound }: AvailableSoundProps) {
@@ -245,6 +238,19 @@ function AvailableSound({ sound }: AvailableSoundProps) { {sound.name}
+ +
) } @@ -274,15 +280,7 @@ interface InlinePreviewProps { function InlinePreview({ sound, position }: InlinePreviewProps) { return (
-
-
-
-
-
-
-
- - + {position + 1} @@ -292,8 +290,45 @@ function InlinePreview({ sound, position }: InlinePreviewProps) {
{sound.name}
-
- Will be added here +
+
+ ) +} + +// Drag overlay component that shows the dragged item +interface DragOverlayContentProps { + sound: Sound | PlaylistSound + position?: number +} + +function DragOverlayContent({ sound, position }: DragOverlayContentProps) { + // If position is provided, show as current playlist style + if (position !== undefined) { + return ( +
+ + {position + 1} + + + + +
+
+ {sound.name} +
+
+
+ ) + } + + // Default available sound style + return ( +
+ + +
+
+ {sound.name}
@@ -517,6 +552,28 @@ export function PlaylistEditPage() { } } + const handleAddSoundToPlaylist = async (soundId: number) => { + try { + // Add at the end - backend should handle position gaps automatically + const position = sounds.length + + await playlistsService.addSoundToPlaylist(playlistId, soundId, position) + toast.success('Sound added to playlist') + + // Refresh playlist sounds + await fetchSounds() + + // Remove the added sound from available sounds + setAvailableSounds(prev => prev.filter(s => s.id !== soundId)) + + // Refresh playlist data to update counts + await fetchPlaylist() + } catch (err) { + const errorMessage = err instanceof Error ? err.message : 'Failed to add sound to playlist' + toast.error(errorMessage) + } + } + const handleRemoveSound = async (soundId: number) => { try { // Find the sound being removed to check if it's EXT type @@ -946,11 +1003,6 @@ export function PlaylistEditPage() { ))} - ) : sounds.length === 0 ? ( -
- -

No sounds in this playlist

-
) : isAddMode ? ( // Add Mode: Split layout with simplified playlist and available sounds
@@ -961,29 +1013,47 @@ export function PlaylistEditPage() { items={sounds.map(sound => `playlist-sound-${sound.id}`)} strategy={verticalListSortingStrategy} > -
- {sounds.map((sound, index) => { - const adjustedIndex = dropPosition !== null && dropPosition <= index ? index + 1 : index - return ( -
- {/* Show inline preview if this is the drop position */} - {dropPosition === index && draggedSound && draggedItem?.startsWith('available-sound-') && ( - - )} - -
- ) - })} - {/* Show inline preview at the end if that's the drop position */} - {dropPosition === sounds.length && draggedSound && draggedItem?.startsWith('available-sound-') && ( - +
+ {sounds.length === 0 ? ( +
+ +

No sounds in playlist

+

Drag sounds here or use + button

+ {/* Show inline preview at position 0 if dragging */} + {dropPosition === 0 && draggedSound && draggedItem?.startsWith('available-sound-') && ( +
+ +
+ )} + {/* Invisible drop area */} + +
+ ) : ( + <> + {sounds.map((sound, index) => { + const adjustedIndex = dropPosition !== null && dropPosition <= index ? index + 1 : index + return ( +
+ {/* Show inline preview if this is the drop position */} + {dropPosition === index && draggedSound && draggedItem?.startsWith('available-sound-') && ( + + )} + +
+ ) + })} + {/* Show inline preview at the end if that's the drop position */} + {dropPosition === sounds.length && draggedSound && draggedItem?.startsWith('available-sound-') && ( + + )} + {/* Invisible drop area at the end */} + + )} - {/* Invisible drop area at the end */} -
@@ -1015,6 +1085,7 @@ export function PlaylistEditPage() { handleAddSoundToPlaylist(soundId)} /> ))}
@@ -1022,9 +1093,16 @@ export function PlaylistEditPage() { )} + ) : sounds.length === 0 ? ( +
+ +

No sounds in this playlist

+

Click the + button to enter add mode

+
) : ( - // Normal Mode: Full table view -
+ // Normal Mode: Full table view (only show table if there are sounds) + sounds.length > 0 && ( +
`table-sound-${sound.id}`)} strategy={verticalListSortingStrategy} @@ -1064,12 +1142,22 @@ export function PlaylistEditPage() { -
+
+ ) )} + {/* Drag Overlay */} + + {draggedSound && ( + + )} + )