51 lines
1.7 KiB
JavaScript
Executable File
51 lines
1.7 KiB
JavaScript
Executable File
import { button, element } from "./dom.js";
|
|
import { formatBytes } from "./format.js";
|
|
|
|
export function renderTree(container, nodes, selection, handlers) {
|
|
if (nodes.length === 0) {
|
|
container.replaceChildren(element("p", "muted", "No files found."));
|
|
return;
|
|
}
|
|
container.replaceChildren(buildList(nodes, selection, handlers));
|
|
}
|
|
|
|
export function topLevelSelection(selection) {
|
|
const paths = [...selection].sort();
|
|
return paths.filter((path) => !paths.some((other) => other !== path && path.startsWith(`${other}/`)));
|
|
}
|
|
|
|
function buildList(nodes, selection, handlers) {
|
|
const list = element("ul", "tree-list");
|
|
for (const node of nodes) list.append(buildNode(node, selection, handlers));
|
|
return list;
|
|
}
|
|
|
|
function buildNode(node, selection, handlers) {
|
|
const item = element("li", "tree-item");
|
|
const row = element("div", "tree-row");
|
|
const label = element("label", "tree-label");
|
|
|
|
const checkbox = document.createElement("input");
|
|
checkbox.type = "checkbox";
|
|
checkbox.checked = selection.has(node.path);
|
|
checkbox.addEventListener("change", () => {
|
|
if (checkbox.checked) selection.add(node.path);
|
|
else selection.delete(node.path);
|
|
handlers.onSelectionChange();
|
|
});
|
|
|
|
const displayName = node.isDir ? `${node.name}/` : node.name;
|
|
label.append(checkbox, element("span", node.isDir ? "tree-name folder" : "tree-name", displayName));
|
|
row.append(label, element("span", "tree-size", formatBytes(node.size)));
|
|
|
|
if (node.isArchive) {
|
|
row.append(button("Extract", "secondary small", () => handlers.onExtract(node.path)));
|
|
}
|
|
|
|
item.append(row);
|
|
if (node.children && node.children.length > 0) {
|
|
item.append(buildList(node.children, selection, handlers));
|
|
}
|
|
return item;
|
|
}
|