From 5a174c9ef08612825391d04f7dce6bf596355770 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Fri, 8 May 2026 11:22:23 -0400 Subject: [PATCH] refactor(web): converge PlaylistTrackRow drag-reorder onto @neodrag/svelte (B4) --- .../lib/components/PlaylistTrackRow.svelte | 39 ++++++++++++++----- web/src/routes/playlists/[id]/+page.svelte | 27 ++++++------- 2 files changed, 40 insertions(+), 26 deletions(-) diff --git a/web/src/lib/components/PlaylistTrackRow.svelte b/web/src/lib/components/PlaylistTrackRow.svelte index e14566ab..275aff1b 100644 --- a/web/src/lib/components/PlaylistTrackRow.svelte +++ b/web/src/lib/components/PlaylistTrackRow.svelte @@ -1,25 +1,23 @@
onDragStart?.(row.position)} - ondragover={(e) => { e.preventDefault(); onDragOver?.(e, row.position); }} - ondrop={(e) => { e.preventDefault(); onDrop?.(e, row.position); }} + use:draggable={{ + axis: 'y', + bounds: 'parent', + disabled: !canDrag, + onDragStart: handleDragStart, + onDragEnd: handleDragEnd + }} > {#if isOwner} (null); - - async function onDrop(toPos: number) { - if (dragFromPos === null || !playlistQuery?.data) { - return; - } - if (dragFromPos === toPos) { - dragFromPos = null; - return; - } - const cur = playlistQuery.data.tracks.map((t) => t.position); - const moved = cur.splice(dragFromPos, 1)[0]; - cur.splice(toPos, 0, moved); - dragFromPos = null; + async function onMove(fromPos: number, toPos: number) { + if (!playlistQuery?.data) return; + const tracks = playlistQuery.data.tracks; + // Clamp toPos so a drag past the list edges resolves cleanly to the + // first/last slot rather than producing an out-of-range index. + const clamped = Math.max(0, Math.min(tracks.length - 1, toPos)); + if (fromPos === clamped) return; + const cur = tracks.map((t) => t.position); + const moved = cur.splice(fromPos, 1)[0]; + cur.splice(clamped, 0, moved); try { await reorderPlaylist(id, cur); await queryClient.invalidateQueries({ queryKey: qk.playlist(id) }); @@ -268,8 +264,7 @@ isOwner={isOwner ?? false} onRemove={onRemove} onPlay={onPlay} - onDragStart={(p) => (dragFromPos = p)} - onDrop={(_, p) => onDrop(p)} + onMove={onMove} /> {/each} {/if}