refactor: changed structure for containerization
This commit is contained in:
170
src/public/static/js/editor.mjs
Normal file
170
src/public/static/js/editor.mjs
Normal file
@ -0,0 +1,170 @@
|
||||
import TracksTable from "./tracks_table.mjs"
|
||||
import IntegrityManager from "./integrity_manager.mjs"
|
||||
import { updateObjectFromJoinedKey } from "./utils.mjs"
|
||||
import { loadMetadata, SeriesMetadata } from "./metadata.mjs"
|
||||
|
||||
export default class Editor {
|
||||
constructor() {
|
||||
const params = new URLSearchParams(window.location.search)
|
||||
this.filename = params.get("f")
|
||||
window.addEventListener("keydown", e => {
|
||||
if (e.key === "s" && e.ctrlKey) {
|
||||
e.preventDefault()
|
||||
this.save()
|
||||
}
|
||||
})
|
||||
|
||||
this.tables = {
|
||||
audio: new TracksTable(this, "audio", "audio-tracks", "audio_tracks"),
|
||||
subtitle: new TracksTable(this, "subtitle", "subtitle-tracks", "subtitle_tracks")
|
||||
}
|
||||
|
||||
this.metadata = null
|
||||
this.data = {}
|
||||
this.dirty = false
|
||||
|
||||
this.integrityMgr = new IntegrityManager(this)
|
||||
|
||||
document.getElementById("check-integrity").addEventListener("click", () => this.checkIntegrity())
|
||||
document.getElementById("improve-all").addEventListener("click", () => this.improveAllNames())
|
||||
document.getElementById("save").addEventListener("click", () => this.save())
|
||||
document.getElementById("reload").addEventListener("click", () => window.location.reload())
|
||||
document.getElementById("toggle-notifs").addEventListener("click", () => this.toggleNotifications())
|
||||
document.getElementById("close-notifs").addEventListener("click", () => this.closeNotifications())
|
||||
document.getElementById("prev-episode").addEventListener("click", () => this.prevEpisode())
|
||||
document.getElementById("next-episode").addEventListener("click", () => this.nextEpisode())
|
||||
|
||||
this.titleInput = document.getElementById("title")
|
||||
this.titleInput.addEventListener("change", () => {
|
||||
this.data.title = this.titleInput.value
|
||||
this.setDirty()
|
||||
})
|
||||
|
||||
this.setup()
|
||||
}
|
||||
|
||||
setup() {
|
||||
document.getElementById("filename").innerText = this.filename
|
||||
this.fetchData()
|
||||
}
|
||||
|
||||
fetchData() {
|
||||
fetch(`/api/file/${this.filename}`).then(res => {
|
||||
if (res.ok) {
|
||||
return res.json()
|
||||
}
|
||||
return null
|
||||
}).then(res => {
|
||||
if (res !== null) {
|
||||
this.metadata = loadMetadata(res)
|
||||
this.displayData()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
displayData() {
|
||||
const seriesToolbar = document.getElementById("series-toolbar")
|
||||
if (this.metadata instanceof SeriesMetadata) {
|
||||
seriesToolbar.classList.add("show")
|
||||
const cur = this.metadata.episodeIdx + 1
|
||||
const tot = this.metadata.episodes.length
|
||||
const epMeta = this.metadata.getCurrentEpisode()
|
||||
const season = epMeta.season
|
||||
const episode = epMeta.episode
|
||||
seriesToolbar.querySelector("#cur-episode").innerText = `S${season}E${episode} (${cur} / ${tot})`
|
||||
} else {
|
||||
seriesToolbar.classList.remove("show")
|
||||
}
|
||||
this.data = this.metadata.getData()
|
||||
this.titleInput.value = this.data.title
|
||||
this.tables.audio.loadTracks(this.data.audio_tracks)
|
||||
this.tables.subtitle.loadTracks(this.data.subtitle_tracks)
|
||||
}
|
||||
|
||||
save() {
|
||||
fetch(`/api/file/${this.filename}`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(this.metadata.data),
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
}).then(res => {
|
||||
if (res.ok) {
|
||||
this.dirty = false
|
||||
document.getElementById("unsaved").classList.remove("show")
|
||||
this.notify("Saved successfully !", "success")
|
||||
} else {
|
||||
this.notify(`Error ${res.status}: ${res.statusText}`, "error", 10000)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
setDirty() {
|
||||
this.dirty = true
|
||||
document.getElementById("unsaved").classList.add("show")
|
||||
}
|
||||
|
||||
editTrack(listKey, trackIdx, key, value) {
|
||||
updateObjectFromJoinedKey(this.data[listKey][trackIdx], key, value)
|
||||
this.setDirty()
|
||||
}
|
||||
|
||||
notify(text, type, duration=5000) {
|
||||
const list = document.getElementById("notifs")
|
||||
const hist = document.getElementById("notifs-hist").querySelector(".list")
|
||||
const notif = document.createElement("div")
|
||||
notif.classList.add("notif")
|
||||
notif.dataset.type = type
|
||||
notif.innerText = text
|
||||
list.appendChild(notif)
|
||||
setTimeout(() => notif.remove(), duration)
|
||||
notif.addEventListener("click", () => notif.remove())
|
||||
hist.prepend(notif.cloneNode(true))
|
||||
}
|
||||
|
||||
checkIntegrity() {
|
||||
if (this.integrityMgr.checkIntegrity()) {
|
||||
this.notify("No integrity error detected !", "success")
|
||||
}
|
||||
}
|
||||
|
||||
improveAllNames() {
|
||||
this.integrityMgr.improveAllNames()
|
||||
this.notify("Improved all names !", "success")
|
||||
}
|
||||
|
||||
toggleNotifications() {
|
||||
const hist = document.getElementById("notifs-hist")
|
||||
if (hist.classList.contains("show")) {
|
||||
this.closeNotifications()
|
||||
} else {
|
||||
this.openNotifications()
|
||||
}
|
||||
}
|
||||
|
||||
openNotifications() {
|
||||
const hist = document.getElementById("notifs-hist")
|
||||
hist.classList.add("show")
|
||||
}
|
||||
|
||||
closeNotifications() {
|
||||
const hist = document.getElementById("notifs-hist")
|
||||
hist.classList.remove("show")
|
||||
}
|
||||
|
||||
prevEpisode() {
|
||||
if (this.metadata instanceof SeriesMetadata) {
|
||||
if (this.metadata.prev()) {
|
||||
this.displayData()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nextEpisode() {
|
||||
if (this.metadata instanceof SeriesMetadata) {
|
||||
if (this.metadata.next()) {
|
||||
this.displayData()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user