195 lines
5.6 KiB
JavaScript
195 lines
5.6 KiB
JavaScript
/** @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"]
|
|
}
|
|
CONSTRAINTS = {
|
|
"flags/default": {
|
|
type: "hotone"
|
|
}
|
|
}
|
|
|
|
constructor(table, callback) {
|
|
this.table = table
|
|
this.headers = this.table.querySelector("thead tr")
|
|
this.body = this.table.querySelector("tbody")
|
|
this.fields = []
|
|
this.tracks = []
|
|
this.callback = callback
|
|
this.hotones = {}
|
|
}
|
|
|
|
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], i)
|
|
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, trackIdx) {
|
|
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
|
|
const hotone = this.CONSTRAINTS[field.key]?.type == "hotone"
|
|
|
|
if (hotone) {
|
|
if (value) {
|
|
if (field.key in this.hotones) {
|
|
alert("Error in metadata file: field ${field.name} is hotone but multiple tracks are enabled ")
|
|
}
|
|
this.hotones[field.key] = input
|
|
}
|
|
input.addEventListener("click", e => {
|
|
console.log("HOTONE")
|
|
if (!input.checked) {
|
|
console.log("Already checked, preventing uncheck")
|
|
e.preventDefault()
|
|
} else {
|
|
if (field.key in this.hotones) {
|
|
this.hotones[field.key].checked = false
|
|
this.hotones[field.key].dispatchEvent(new Event("change"))
|
|
}
|
|
this.hotones[field.key] = input
|
|
}
|
|
})
|
|
}
|
|
input.addEventListener("change", () => {
|
|
this.callback(trackIdx, field.key, input.checked)
|
|
})
|
|
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
|
|
}
|
|
input.dataset.key = field.key
|
|
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"), (i, key, value) => {
|
|
console.log(i, key, value)
|
|
})
|
|
subtitleTable = new TracksTable(document.getElementById("subtitle-tracks"), (i, key, value) => {
|
|
console.log(i, key, value)
|
|
})
|
|
|
|
const params = new URLSearchParams(window.location.search)
|
|
const file = params.get("f")
|
|
document.getElementById("filename").innerText = file
|
|
|
|
fetchData(file)
|
|
}) |