feat(web): subtitle lane under the signal chain
This commit is contained in:
+51
-1
@@ -1,4 +1,4 @@
|
||||
import { type CheckStatus, type Probe, probeHealth } from "./health";
|
||||
import { type Check, type CheckStatus, type Probe, type SubtitleHealth, probeHealth } from "./health";
|
||||
import {
|
||||
fetchLibrary,
|
||||
type LibrarySeries,
|
||||
@@ -171,6 +171,52 @@ function setModule(refs: ModuleRefs, state: string, tone: Tone, word: string, de
|
||||
refs.detail.textContent = detail ?? refs.defaultDetail;
|
||||
}
|
||||
|
||||
/** One lamp of the subtitle lane (#200): same module shape as the chain,
|
||||
* rendered per poll — which providers are in use is a settings row, not
|
||||
* markup. */
|
||||
function subtitleModule(name: string, role: string, check: Check): HTMLElement {
|
||||
const article = document.createElement("article");
|
||||
article.className = "module";
|
||||
|
||||
const head = document.createElement("header");
|
||||
head.className = "module-head";
|
||||
const lamp = document.createElement("span");
|
||||
lamp.className = "lamp";
|
||||
lamp.dataset.state = check.status;
|
||||
const title = document.createElement("h2");
|
||||
title.className = "module-name";
|
||||
title.textContent = name;
|
||||
const status = document.createElement("span");
|
||||
status.className = "module-status readout";
|
||||
status.dataset.tone = TONE_BY_STATUS[check.status];
|
||||
status.textContent = check.status;
|
||||
head.append(lamp, title, status);
|
||||
|
||||
const roleLine = document.createElement("p");
|
||||
roleLine.className = "module-role";
|
||||
roleLine.textContent = role;
|
||||
const detail = document.createElement("p");
|
||||
detail.className = "module-detail readout";
|
||||
detail.textContent = check.detail ?? "";
|
||||
|
||||
article.append(head, roleLine, detail);
|
||||
return article;
|
||||
}
|
||||
|
||||
function renderSubtitles(subLane: HTMLElement, subs: SubtitleHealth) {
|
||||
const entries: { name: string; role: string; check: Check }[] = subs.providers.map(
|
||||
(provider) => ({ name: provider.id, role: "subtitles in", check: provider }),
|
||||
);
|
||||
if (subs.translation) {
|
||||
entries.push({ name: "translate", role: "engine out", check: subs.translation });
|
||||
}
|
||||
entries.push({ name: "alass", role: "timing sync", check: subs.alass });
|
||||
entries.push({ name: "ffmpeg", role: "track extraction", check: subs.ffmpeg });
|
||||
|
||||
subLane.replaceChildren(...entries.map((entry) => subtitleModule(entry.name, entry.role, entry.check)));
|
||||
subLane.hidden = false;
|
||||
}
|
||||
|
||||
function must<T extends Element>(selector: string): T {
|
||||
const element = document.querySelector<T>(selector);
|
||||
if (!element) {
|
||||
@@ -181,6 +227,7 @@ function must<T extends Element>(selector: string): T {
|
||||
|
||||
function main() {
|
||||
const chain = must<HTMLElement>(".chain");
|
||||
const subLane = must<HTMLElement>("#chain-subs");
|
||||
const masterLamp = must<HTMLElement>("#master-lamp");
|
||||
const version = must<HTMLElement>("#version");
|
||||
|
||||
@@ -235,6 +282,8 @@ function main() {
|
||||
for (const name of ["tmdb", "prowlarr", "master"] as const) {
|
||||
setTrace(name, null);
|
||||
}
|
||||
subLane.hidden = true;
|
||||
subLane.replaceChildren();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -259,6 +308,7 @@ function main() {
|
||||
setTrace(name, TONE_BY_STATUS[check.status]);
|
||||
}
|
||||
}
|
||||
renderSubtitles(subLane, report.subtitles);
|
||||
}
|
||||
|
||||
let inFlight = false;
|
||||
|
||||
Reference in New Issue
Block a user