fix(ui): harden navigation and queue interactions

This commit is contained in:
NimBold
2026-07-28 22:11:38 +03:30
parent 7e8f1c7d7b
commit 62f8c83c57
9 changed files with 299 additions and 68 deletions
+53
View File
@@ -0,0 +1,53 @@
export interface DownloadSelectionResult {
selectedIds: Set<string>;
lastSelectedId: string | null;
}
interface DownloadSelectionOptions {
orderedIds: readonly string[];
selectedIds: ReadonlySet<string>;
lastSelectedId: string | null;
targetId: string;
extendRange: boolean;
toggle: boolean;
}
/** Apply the table's click-selection rules without depending on React state timing. */
export const updateDownloadSelection = ({
orderedIds,
selectedIds,
lastSelectedId,
targetId,
extendRange,
toggle,
}: DownloadSelectionOptions): DownloadSelectionResult => {
const targetIndex = orderedIds.indexOf(targetId);
if (targetIndex === -1) {
return { selectedIds: new Set(selectedIds), lastSelectedId };
}
if (extendRange && lastSelectedId) {
const anchorIndex = orderedIds.indexOf(lastSelectedId);
if (anchorIndex !== -1) {
const nextSelectedIds = toggle ? new Set(selectedIds) : new Set<string>();
const start = Math.min(anchorIndex, targetIndex);
const end = Math.max(anchorIndex, targetIndex);
for (let index = start; index <= end; index += 1) {
nextSelectedIds.add(orderedIds[index]);
}
return { selectedIds: nextSelectedIds, lastSelectedId };
}
}
if (toggle) {
const nextSelectedIds = new Set(selectedIds);
if (nextSelectedIds.has(targetId)) {
nextSelectedIds.delete(targetId);
} else {
nextSelectedIds.add(targetId);
}
return { selectedIds: nextSelectedIds, lastSelectedId: targetId };
}
return { selectedIds: new Set([targetId]), lastSelectedId: targetId };
};