diff --git a/frontend/pages/warrens/files.vue b/frontend/pages/warrens/files.vue index 52124ba..0aabfdc 100644 --- a/frontend/pages/warrens/files.vue +++ b/frontend/pages/warrens/files.vue @@ -79,13 +79,79 @@ function onDrop(files: File[] | null, e: DragEvent) { } } +/** + * Returns whether the event was a selection event (so further execution can be stopped) + */ +function handleEntrySelectionClick( + selectedEntry: DirectoryEntry, + event: MouseEvent +): boolean { + if (!event.ctrlKey && !event.shiftKey) { + return false; + } + + if (warrenStore.current == null || warrenStore.current.dir == null) { + return true; + } + + if (event.ctrlKey || (event.shiftKey && warrenStore.selection.size === 0)) { + if ( + warrenStore.toggleSelection(selectedEntry) || + warrenStore.selectionRangeAnchor == null + ) { + warrenStore.setSelectedRangeAnchor(selectedEntry); + } + return true; + } + + if (!event.shiftKey) { + return false; + } + + const anchor = warrenStore.selectionRangeAnchor; + + if (anchor == null) { + return true; + } + + const entries = warrenStore.current.dir.entries.toSorted((a, b) => + a.name.localeCompare(b.name) + ); + const anchorIndex = entries.findIndex( + (entry) => entry.name === anchor.name + ); + + const clickedIndex = entries.findIndex( + (e) => e.name === selectedEntry.name + ); + + // NOTE: This has to change if there are ever multiple sorting orders + + const targetSelection = []; + + if (clickedIndex > anchorIndex) { + for (let i = anchorIndex; i <= clickedIndex; i++) { + targetSelection.push(entries[i]); + } + } else { + for (let i = clickedIndex; i <= anchorIndex; i++) { + targetSelection.push(entries[i]); + } + } + + warrenStore.setSelection(targetSelection); + + return true; +} + async function onEntryClicked(entry: DirectoryEntry, event: MouseEvent) { + event.stopPropagation(); + if (warrenStore.loading || warrenStore.current == null) { return; } - if (event.ctrlKey) { - warrenStore.toggleSelection(entry); + if (handleEntrySelectionClick(entry, event)) { return; } @@ -156,10 +222,14 @@ async function onEntryDelete(entry: DirectoryEntry, force: boolean) { function onBack() { warrenStore.backCurrentPath(); } + +function onParentClick() { + warrenStore.clearSelection(); +}