From ca6dd87531b2b8ef92ed14689f46946b6fcf9717 Mon Sep 17 00:00:00 2001 From: Honey Date: Tue, 28 Apr 2026 21:21:13 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20drag-and-drop=20=E2=80=94=20set=20dragga?= =?UTF-8?q?ble=20upfront,=20add=20Firefox=20setData,=20fix=20duplicate=20d?= =?UTF-8?q?ragend?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit draggable=true must be set before any mouse event (not on mousedown). Firefox requires setData() for drag to work. Removed duplicate dragend listener that was resetting draggable=false and conflicting with the first. Co-Authored-By: Claude Sonnet 4.6 --- src/views.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/views.js b/src/views.js index 250cfa4..d439307 100644 --- a/src/views.js +++ b/src/views.js @@ -558,19 +558,23 @@ function _initPlaylistDragDrop(container, songs, pl) { handle.innerHTML = ''; item.insertBefore(handle, item.firstChild); item._songRef = songs[i]; + item.draggable = true; // set upfront so browser registers it before any event item.addEventListener('dragstart', e => { if (!e.target.closest('.pl-drag-handle')) { e.preventDefault(); return; } dragSrc = item; e.dataTransfer.effectAllowed = 'move'; + e.dataTransfer.setData('text/plain', ''); // required by Firefox setTimeout(() => item.classList.add('dragging'), 0); }); item.addEventListener('dragend', () => { + dragSrc = null; item.classList.remove('dragging'); container.querySelectorAll('.drag-over').forEach(el => el.classList.remove('drag-over')); }); item.addEventListener('dragover', e => { e.preventDefault(); + e.dataTransfer.dropEffect = 'move'; if (item === dragSrc) return; container.querySelectorAll('.drag-over').forEach(el => el.classList.remove('drag-over')); item.classList.add('drag-over'); @@ -580,6 +584,7 @@ function _initPlaylistDragDrop(container, songs, pl) { }); item.addEventListener('drop', e => { e.preventDefault(); + e.stopPropagation(); if (!dragSrc || item === dragSrc) return; item.classList.remove('drag-over'); const allItems = Array.from(container.children); @@ -594,13 +599,10 @@ function _initPlaylistDragDrop(container, songs, pl) { const n = el.querySelector('.song-num'); if (n) n.textContent = idx + 1; }); - // Debounced save + // Debounced save to Navidrome clearTimeout(saveTimer); saveTimer = setTimeout(() => _savePlaylistOrder(pl, songs), 800); }); - - handle.addEventListener('mousedown', () => { item.draggable = true; }); - item.addEventListener('dragend', () => { item.draggable = false; }); }); }