/** @type TracksTable */ let audioTable /** @type TracksTable */ let subtitleTable function flattenObj(obj) { const res = {} Object.entries(obj).forEach(([key, value]) => { if (typeof value === "object") { value = flattenObj(value) Object.entries(value).forEach(([key2, value2]) => { res[key + "/" + key2] = value2 }) } else { res[key] = value } }) return res } class TracksTable { OPTIONS = { "language": ["fre", "eng"] } constructor(table) { this.table = table this.headers = this.table.querySelector("thead tr") this.body = this.table.querySelector("tbody") this.fields = [] this.tracks = [] } showTracks(tracks) { this.tracks = tracks.map(flattenObj) this.clear() if (tracks.length === 0) { return } this.detectFields() this.addHeaders() this.tracks.forEach((track, i) => { const tr = document.createElement("tr") tr.dataset.i = i this.fields.forEach(field => { const td = tr.insertCell(-1) const input = this.makeInput(field, track[field.key]) td.appendChild(input) }) this.body.appendChild(tr) }) } clear() { this.headers.innerHTML = "" this.body.innerHTML = "" this.fields = [] } detectFields() { Object.entries(this.tracks[0]).forEach(([key, value]) => { let type = { boolean: "bool", number: "num" }[typeof value] ?? "str" if (key === "language") { type = "sel" } const name = key.split("/").slice(-1)[0] this.fields.push({name, type, key}) }) } addHeaders() { this.fields.forEach(field => { const th = document.createElement("th") th.innerText = field.name this.headers.appendChild(th) }) } makeInput(field, value) { let input = document.createElement("input") switch (field.type) { case "num": input.type = "number" input.value = value break case "str": input.type = "text" input.value = value break case "bool": input.type = "checkbox" input.checked = value break case "sel": input = document.createElement("select") const options = this.OPTIONS[field.name] options.forEach(option => { const opt = document.createElement("option") opt.innerText = option opt.value = option input.appendChild(opt) }) input.value = value default: break } return input } } function fetchData(filename) { fetch("/api/file", { method: "POST", body: JSON.stringify({ file: filename }), headers: { "Content-Type": "application/json" } }).then(res => { if (res.ok) { return res.json() } return null }).then(res => { if (res !== null) { displayData(res) } }) } function displayData(data) { document.getElementById("title").value = data.title audioTable.showTracks(data.audio_tracks) subtitleTable.showTracks(data.subtitle_tracks) } window.addEventListener("load", () => { audioTable = new TracksTable(document.getElementById("audio-tracks")) subtitleTable = new TracksTable(document.getElementById("subtitle-tracks")) const params = new URLSearchParams(window.location.search) const file = params.get("f") document.getElementById("filename").innerText = file fetchData(file) })