Profiles Phase 2 (drag): make the hybrid-source reorder actually draggable
The hybrid download-source list set item.draggable=true and the help text said "drag to reorder", but no drag handlers were wired — only the arrow buttons worked (and _syncHybridOrderFromDOM was dead code). Wired real dragstart/dragover/drop on each item, reordering _hybridVisualOrder (the same model moveHybridSource uses) then rebuilding + autosaving. Added grab/grabbing cursors + a dragging state. The arrow buttons still work unchanged.
This commit is contained in:
parent
4ef12d7ddf
commit
bb0f68a8bf
2 changed files with 37 additions and 0 deletions
|
|
@ -699,6 +699,21 @@ function buildHybridSourceList() {
|
||||||
</label>
|
</label>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
// Real drag-to-reorder (the help text promised it; previously only the
|
||||||
|
// arrow buttons worked — item.draggable was set with no handlers).
|
||||||
|
item.addEventListener('dragstart', (e) => {
|
||||||
|
e.dataTransfer.effectAllowed = 'move';
|
||||||
|
e.dataTransfer.setData('text/plain', srcId);
|
||||||
|
item.classList.add('dragging');
|
||||||
|
});
|
||||||
|
item.addEventListener('dragend', () => item.classList.remove('dragging'));
|
||||||
|
item.addEventListener('dragover', (e) => { e.preventDefault(); e.dataTransfer.dropEffect = 'move'; });
|
||||||
|
item.addEventListener('drop', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const draggedId = e.dataTransfer.getData('text/plain');
|
||||||
|
if (draggedId && draggedId !== srcId) _reorderHybridSource(draggedId, srcId);
|
||||||
|
});
|
||||||
|
|
||||||
container.appendChild(item);
|
container.appendChild(item);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -723,6 +738,22 @@ function moveHybridSource(srcId, direction) {
|
||||||
debouncedAutoSaveSettings();
|
debouncedAutoSaveSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _reorderHybridSource(draggedId, targetId) {
|
||||||
|
// Move draggedId to just before targetId in the visual order, then rebuild
|
||||||
|
// the enabled subset + persist — same model moveHybridSource uses.
|
||||||
|
if (!_hybridVisualOrder) return;
|
||||||
|
const from = _hybridVisualOrder.indexOf(draggedId);
|
||||||
|
if (from < 0) return;
|
||||||
|
_hybridVisualOrder.splice(from, 1);
|
||||||
|
const to = _hybridVisualOrder.indexOf(targetId);
|
||||||
|
if (to < 0) { _hybridVisualOrder.splice(from, 0, draggedId); return; } // target gone — undo
|
||||||
|
_hybridVisualOrder.splice(to, 0, draggedId);
|
||||||
|
_hybridSourceOrder = _hybridVisualOrder.filter(id => _hybridSourceEnabled[id] !== false);
|
||||||
|
buildHybridSourceList();
|
||||||
|
updateDownloadSourceUI();
|
||||||
|
debouncedAutoSaveSettings();
|
||||||
|
}
|
||||||
|
|
||||||
function toggleHybridSource(srcId, enabled) {
|
function toggleHybridSource(srcId, enabled) {
|
||||||
_hybridSourceEnabled[srcId] = enabled;
|
_hybridSourceEnabled[srcId] = enabled;
|
||||||
// Rebuild enabled order from visual order so priority matches position
|
// Rebuild enabled order from visual order so priority matches position
|
||||||
|
|
|
||||||
|
|
@ -55534,6 +55534,12 @@ tr.tag-diff-same {
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
cursor: grab;
|
||||||
|
}
|
||||||
|
.hybrid-source-item.dragging {
|
||||||
|
opacity: 0.5;
|
||||||
|
cursor: grabbing;
|
||||||
|
border-color: rgb(var(--accent-light-rgb));
|
||||||
}
|
}
|
||||||
.hybrid-source-item:hover {
|
.hybrid-source-item:hover {
|
||||||
border-color: rgba(255, 255, 255, 0.12);
|
border-color: rgba(255, 255, 255, 0.12);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue