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>';
|
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.insertBefore(handle, item.firstChild);
|
||||||
item._songRef = songs[i];
|
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 => {
|
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;
|
dragSrc = item;
|
||||||
e.dataTransfer.effectAllowed = 'move';
|
e.dataTransfer.effectAllowed = 'move';
|
||||||
e.dataTransfer.setData('text/plain', ''); // required by Firefox
|
e.dataTransfer.setData('text/plain', ''); // required by Firefox
|
||||||
setTimeout(() => item.classList.add('dragging'), 0);
|
setTimeout(() => item.classList.add('dragging'), 0);
|
||||||
});
|
});
|
||||||
item.addEventListener('dragend', () => {
|
item.addEventListener('dragend', () => {
|
||||||
|
fromHandle = false;
|
||||||
|
item.draggable = false;
|
||||||
dragSrc = null;
|
dragSrc = null;
|
||||||
item.classList.remove('dragging');
|
item.classList.remove('dragging');
|
||||||
container.querySelectorAll('.drag-over').forEach(el => el.classList.remove('drag-over'));
|
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 fromIdx = allItems.indexOf(dragSrc);
|
||||||
const toIdx = allItems.indexOf(item);
|
const toIdx = allItems.indexOf(item);
|
||||||
container.insertBefore(dragSrc, fromIdx < toIdx ? item.nextSibling : 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);
|
const newOrder = Array.from(container.children).map(el => el._songRef);
|
||||||
songs.splice(0, songs.length, ...newOrder);
|
songs.splice(0, songs.length, ...newOrder);
|
||||||
// Update track numbers
|
|
||||||
Array.from(container.children).forEach((el, idx) => {
|
Array.from(container.children).forEach((el, idx) => {
|
||||||
const n = el.querySelector('.song-num');
|
const n = el.querySelector('.song-num');
|
||||||
if (n) n.textContent = idx + 1;
|
if (n) n.textContent = idx + 1;
|
||||||
});
|
});
|
||||||
// Debounced save to Navidrome
|
|
||||||
clearTimeout(saveTimer);
|
clearTimeout(saveTimer);
|
||||||
saveTimer = setTimeout(() => _savePlaylistOrder(pl, songs), 800);
|
saveTimer = setTimeout(() => _savePlaylistOrder(pl, songs), 800);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in new issue
Block a user