From 194c11ece25f2da746fb92a0769e0552c480e22b Mon Sep 17 00:00:00 2001 From: Zaki <18zaki18@gmail.com> Date: Sat, 9 May 2026 23:36:39 +0100 Subject: [PATCH] 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. --- js/app.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/js/app.js b/js/app.js index 6a4b94d..9fdbc80 100644 --- a/js/app.js +++ b/js/app.js @@ -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;