Fix Shift+arrow range selection: track anchor (fixed) and focus (moving) separately

Previous approach always started from the lowest-indexed selected entry, causing the range to snap to anchor on arrow reversal. Now arrowFocus tracks the moving end; arrowAnchor stays fixed. Non-Shift arrow resets both to the new position.
This commit is contained in:
2026-05-09 23:36:39 +01:00
parent 0a0e380b95
commit 194c11ece2
+9 -4
View File
@@ -23,6 +23,7 @@ let showTrash = false;
let selectedIds = new Set();
let lastSelectedId = null;
let arrowAnchor = -1;
let arrowFocus = -1;
let rectState = { active: false, startX: 0, startY: 0, el: null, started: false };
// ==================== SOUND ====================
@@ -1083,6 +1084,7 @@ function toggleSelectEntry(id, e) {
}
lastSelectedId = id;
arrowAnchor = -1;
arrowFocus = -1;
updateBatchBar();
render();
}
@@ -1091,6 +1093,7 @@ function clearSelection() {
selectedIds.clear();
lastSelectedId = null;
arrowAnchor = -1;
arrowFocus = -1;
hideBatchBar();
render();
}
@@ -1426,8 +1429,8 @@ document.addEventListener('keydown', function(e) {
const filtered = getFilteredEntries();
if (!filtered.length) return;
const isNext = e.key === 'ArrowDown' || e.key === 'ArrowRight';
let idx = -1;
if (selectedIds.size > 0) {
let idx = arrowFocus >= 0 ? arrowFocus : -1;
if (idx < 0 && selectedIds.size > 0) {
const firstId = [...selectedIds][0];
idx = filtered.findIndex(e => e.id == firstId);
}
@@ -1440,13 +1443,15 @@ document.addEventListener('keydown', function(e) {
}
if (e.shiftKey) {
if (arrowAnchor < 0) arrowAnchor = idx;
const start = Math.min(arrowAnchor, idx), end = Math.max(arrowAnchor, idx);
arrowFocus = idx;
const start = Math.min(arrowAnchor, arrowFocus), end = Math.max(arrowAnchor, arrowFocus);
selectedIds.clear();
for (let i = start; i <= end; i++) selectedIds.add(filtered[i].id);
} else {
selectedIds.clear();
selectedIds.add(filtered[idx].id);
if (arrowAnchor < 0) arrowAnchor = idx;
arrowAnchor = idx;
arrowFocus = idx;
}
updateBatchBar(); render(); playSound('click');
return;