feat (ui): selecteer meerdere bestanden tegelijkertijd

This commit is contained in:
kodi
2026-03-09 18:24:00 +01:00
parent c5b873c63a
commit 4941b4161c
4 changed files with 101 additions and 9 deletions
+53 -9
View File
@@ -17,6 +17,7 @@
modalKnownFiles: {},
modalFileFilter: "",
modalVisibleFiles: [],
modalSelectionAnchorPath: null,
syncScrolling: false,
settings: {
set_file_date_to_first_aired_date: false,
@@ -755,6 +756,7 @@
};
});
state.modalFileFilter = "";
state.modalSelectionAnchorPath = null;
el.fileModalTitle.textContent = "File Discovery";
el.modalAddSelectedFilesBtn.style.display = "";
if (el.modalFileFilterInput) {
@@ -819,22 +821,62 @@
const isSelected = state.modalSelectedFilePaths.has(file.path);
if (isSelected) li.classList.add("selected");
if (state.modalSelectionAnchorPath && state.modalSelectionAnchorPath === file.path) {
li.classList.add("modal-anchor");
}
li.addEventListener("click", () => {
if (state.modalSelectedFilePaths.has(file.path)) {
state.modalSelectedFilePaths.delete(file.path);
li.classList.remove("selected");
} else {
state.modalSelectedFilePaths.add(file.path);
li.classList.add("selected");
}
updateModalSelectionCount();
li.addEventListener("click", (event) => {
handleModalFileRowClick(file.path, event);
});
el.modalFilesList.appendChild(li);
});
updateModalSelectionCount();
}
function handleModalFileRowClick(path, event) {
const clickedPath = (path || "").toString().trim();
if (!clickedPath) return;
const visiblePaths = (state.modalVisibleFiles || [])
.map((f) => (f && f.path ? f.path : ""))
.filter((p) => p);
const isShift = !!(event && event.shiftKey);
const isToggle = !!(event && (event.ctrlKey || event.metaKey));
if (isShift) {
const anchor = state.modalSelectionAnchorPath || "";
const from = visiblePaths.indexOf(anchor);
const to = visiblePaths.indexOf(clickedPath);
if (from >= 0 && to >= 0) {
const start = Math.min(from, to);
const end = Math.max(from, to);
const rangePaths = visiblePaths.slice(start, end + 1);
state.modalSelectedFilePaths = new Set(rangePaths);
} else {
// Fallback: no valid anchor in current visible list.
state.modalSelectedFilePaths = new Set([clickedPath]);
}
state.modalSelectionAnchorPath = clickedPath;
renderModalFiles();
return;
}
if (isToggle) {
if (state.modalSelectedFilePaths.has(clickedPath)) {
state.modalSelectedFilePaths.delete(clickedPath);
} else {
state.modalSelectedFilePaths.add(clickedPath);
}
state.modalSelectionAnchorPath = clickedPath;
renderModalFiles();
return;
}
state.modalSelectedFilePaths = new Set([clickedPath]);
state.modalSelectionAnchorPath = clickedPath;
renderModalFiles();
}
async function loadModalFiles(subpath) {
const rootId = el.modalRootSelect.value;
const chosenSubpath = (subpath || "").trim();
@@ -845,6 +887,7 @@
const data = await api(
`/api/files/discover?root_id=${encodeURIComponent(rootId)}&subpath=${encodeURIComponent(chosenSubpath)}&recursive=${recursive}&limit=200`
);
state.modalSelectionAnchorPath = null;
state.modalFiles = data.items || [];
state.modalFiles.forEach((file) => {
const path = file.path || "";
@@ -891,6 +934,7 @@
function clearModalSelection() {
state.modalSelectedFilePaths.clear();
state.modalSelectionAnchorPath = null;
renderModalFiles();
}
+4
View File
@@ -506,6 +506,10 @@ button.secondary {
cursor: pointer;
}
#modalFilesList li.modal-anchor {
box-shadow: inset 0 0 0 1px var(--button-primary-border);
}
.modal-files-tools {
margin-bottom: 8px;
}