let fileNodes = [] function makeFilm(meta) { const file = document.getElementById("film-template").cloneNode(true) file.querySelector(".title").innerText = meta.title return file } function makeSeries(meta) { const file = document.getElementById("series-template").cloneNode(true) file.querySelector(".title").innerText = meta.title file.querySelector(".episodes .num").innerText = meta.episodes return file } function makeFile(meta) { let file switch (meta.type) { case "film": file = makeFilm(meta) break case "series": file = makeSeries(meta) break default: throw new Error(`Invalid file type '${meta.type}'`) } file.title = meta.filename file.id = null file.classList.remove("template") const url = new URL("/edit/", window.location.origin) url.searchParams.set("f", meta.filename) file.href = url.href return file } /** * * @param {object[]} files */ function addFiles(files) { const list = document.getElementById("files") list.innerHTML = "" const filenames = files.map(meta => meta.filename) // Copy array because sort changes it in place Array.from(filenames).sort().forEach(filename => { const i = filenames.indexOf(filename) const meta = files[i] const file = makeFile(meta) list.appendChild(file) fileNodes.push([meta, file]) }) } function sortFiles() { const sortBy = document.getElementById("sort-by").value const sortDesc = document.getElementById("sort-desc").checked const filter = document.getElementById("filter").value fileNodes.forEach(([meta, node]) => { if (node.classList.contains(filter) || filter === "all") { node.classList.remove("hidden") } else { node.classList.add("hidden") } }) let changed = false do { changed = false for (let i = 0; i < fileNodes.length - 1; i++) { /** @type {[object, HTMLElement]} */ const pair1 = fileNodes[i] /** @type {[object, HTMLElement]} */ const pair2 = fileNodes[i + 1] const [meta1, node1] = pair1 const [meta2, node2] = pair2 let swap = false if (sortDesc) { swap = !(meta1[sortBy] >= meta2[sortBy]) } else { swap = !(meta2[sortBy] >= meta1[sortBy]) } if (swap) { fileNodes[i] = pair2 fileNodes[i + 1] = pair1 node2.parentElement.insertBefore(node2, node1) changed = true } } } while (changed) } window.addEventListener("load", () => { fetch("/api/files").then(res => { return res.json() }).then(files => { addFiles(files) sortFiles() }) document.getElementById("sort-by").addEventListener("change", () => sortFiles()) document.getElementById("sort-desc").addEventListener("click", () => sortFiles()) document.getElementById("filter").addEventListener("change", () => sortFiles()) })