fix: drag-and-drop — use fromHandle bool instead of e.target check
e.target in dragstart is always the draggable item element, never the
handle child — so closest('.pl-drag-handle') always returned null and
every drag was cancelled. Now mousedown on handle sets fromHandle=true
and item.draggable=true; dragstart checks the bool instead.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
ca6dd87531
commit
3988d18182
1 file changed
+8
-5
+8
-5
@@ -558,16 +558,22 @@ function _initPlaylistDragDrop(container, songs, pl) {
|
||||
handle.innerHTML = '<svg width="10" height="14" viewBox="0 0 10 14" fill="currentColor"><circle cx="3" cy="2" r="1.3"/><circle cx="7" cy="2" r="1.3"/><circle cx="3" cy="7" r="1.3"/><circle cx="7" cy="7" r="1.3"/><circle cx="3" cy="12" r="1.3"/><circle cx="7" cy="12" r="1.3"/></svg>';
|
||||
item.insertBefore(handle, item.firstChild);
|
||||
item._songRef = songs[i];
|
||||
item.draggable = true; // set upfront so browser registers it before any event
|
||||
|
||||
// Track whether drag started from the handle (e.target in dragstart is always the item, not the handle)
|
||||
let fromHandle = false;
|
||||
handle.addEventListener('mousedown', () => { fromHandle = true; item.draggable = true; });
|
||||
|
||||
item.addEventListener('dragstart', e => {
|
||||
if (!e.target.closest('.pl-drag-handle')) { e.preventDefault(); return; }
|
||||
if (!fromHandle) { e.preventDefault(); item.draggable = false; return; }
|
||||
fromHandle = false;
|
||||
dragSrc = item;
|
||||
e.dataTransfer.effectAllowed = 'move';
|
||||
e.dataTransfer.setData('text/plain', ''); // required by Firefox
|
||||
setTimeout(() => item.classList.add('dragging'), 0);
|
||||
});
|
||||
item.addEventListener('dragend', () => {
|
||||
fromHandle = false;
|
||||
item.draggable = false;
|
||||
dragSrc = null;
|
||||
item.classList.remove('dragging');
|
||||
container.querySelectorAll('.drag-over').forEach(el => el.classList.remove('drag-over'));
|
||||
@@ -591,15 +597,12 @@ function _initPlaylistDragDrop(container, songs, pl) {
|
||||
const fromIdx = allItems.indexOf(dragSrc);
|
||||
const toIdx = allItems.indexOf(item);
|
||||
container.insertBefore(dragSrc, fromIdx < toIdx ? item.nextSibling : item);
|
||||
// Sync songs array to new DOM order
|
||||
const newOrder = Array.from(container.children).map(el => el._songRef);
|
||||
songs.splice(0, songs.length, ...newOrder);
|
||||
// Update track numbers
|
||||
Array.from(container.children).forEach((el, idx) => {
|
||||
const n = el.querySelector('.song-num');
|
||||
if (n) n.textContent = idx + 1;
|
||||
});
|
||||
// Debounced save to Navidrome
|
||||
clearTimeout(saveTimer);
|
||||
saveTimer = setTimeout(() => _savePlaylistOrder(pl, songs), 800);
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user