Fix shift+arrow anchor and detail view arrow navigation

Shift+arrow now uses arrowAnchor (set on first arrow press) instead of lastSelectedId (which was updated on each non-Shift move). Fixes 'only 2 entries' bug. Detail view: fixed inverted auth check for ArrowLeft/Right; general arrow handler now excludes detail view.
This commit is contained in:
2026-05-09 23:32:36 +01:00
parent 3802f1fc23
commit 0a0e380b95
+8 -6
View File
@@ -22,6 +22,7 @@ let draggedId = null;
let showTrash = false; let showTrash = false;
let selectedIds = new Set(); let selectedIds = new Set();
let lastSelectedId = null; let lastSelectedId = null;
let arrowAnchor = -1;
let rectState = { active: false, startX: 0, startY: 0, el: null, started: false }; let rectState = { active: false, startX: 0, startY: 0, el: null, started: false };
// ==================== SOUND ==================== // ==================== SOUND ====================
@@ -1081,6 +1082,7 @@ function toggleSelectEntry(id, e) {
else { selectedIds.clear(); selectedIds.add(id); } else { selectedIds.clear(); selectedIds.add(id); }
} }
lastSelectedId = id; lastSelectedId = id;
arrowAnchor = -1;
updateBatchBar(); updateBatchBar();
render(); render();
} }
@@ -1088,6 +1090,7 @@ function toggleSelectEntry(id, e) {
function clearSelection() { function clearSelection() {
selectedIds.clear(); selectedIds.clear();
lastSelectedId = null; lastSelectedId = null;
arrowAnchor = -1;
hideBatchBar(); hideBatchBar();
render(); render();
} }
@@ -1411,14 +1414,14 @@ document.addEventListener('keydown', function(e) {
} }
// Arrow keys for detail view navigation // Arrow keys for detail view navigation
if ((e.key === 'ArrowLeft' || e.key === 'ArrowRight') && !isInput && view === 'detail' && !document.getElementById('authSection').classList.contains('hidden')) { if ((e.key === 'ArrowLeft' || e.key === 'ArrowRight') && !isInput && view === 'detail' && document.getElementById('authSection').classList.contains('hidden')) {
e.preventDefault(); e.preventDefault();
goDetail(e.key === 'ArrowLeft' ? -1 : 1); goDetail(e.key === 'ArrowLeft' ? -1 : 1);
return; return;
} }
// Arrow keys — navigate entries in vault // Arrow keys — navigate entries in vault
if ((e.key === 'ArrowUp' || e.key === 'ArrowDown' || e.key === 'ArrowLeft' || e.key === 'ArrowRight') && !isInput && document.getElementById('authSection').classList.contains('hidden')) { if ((e.key === 'ArrowUp' || e.key === 'ArrowDown' || e.key === 'ArrowLeft' || e.key === 'ArrowRight') && !isInput && document.getElementById('authSection').classList.contains('hidden') && view !== 'detail') {
e.preventDefault(); e.preventDefault();
const filtered = getFilteredEntries(); const filtered = getFilteredEntries();
if (!filtered.length) return; if (!filtered.length) return;
@@ -1436,15 +1439,14 @@ document.addEventListener('keydown', function(e) {
else idx = idx > 0 ? idx - 1 : filtered.length - 1; else idx = idx > 0 ? idx - 1 : filtered.length - 1;
} }
if (e.shiftKey) { if (e.shiftKey) {
const anchorId = lastSelectedId !== null ? lastSelectedId : filtered[idx].id; if (arrowAnchor < 0) arrowAnchor = idx;
const anchor = filtered.findIndex(e => e.id == anchorId); const start = Math.min(arrowAnchor, idx), end = Math.max(arrowAnchor, idx);
const start = Math.min(anchor, idx), end = Math.max(anchor, idx);
selectedIds.clear(); selectedIds.clear();
for (let i = start; i <= end; i++) selectedIds.add(filtered[i].id); for (let i = start; i <= end; i++) selectedIds.add(filtered[i].id);
} else { } else {
selectedIds.clear(); selectedIds.clear();
selectedIds.add(filtered[idx].id); selectedIds.add(filtered[idx].id);
lastSelectedId = filtered[idx].id; if (arrowAnchor < 0) arrowAnchor = idx;
} }
updateBatchBar(); render(); playSound('click'); updateBatchBar(); render(); playSound('click');
return; return;