Watch the DiGiCo FOH console inside AUDIO; "+ Key" asks for a group when the deck is full
- DIGICO (in the AUDIO group): Companion's DiGiCo_FOH connection, the digico-relay helper on NA Ingest (hold AUDIO restarts it), and a ping to the console at 10.1.60.100 (the OSC connection reads good even with the console off). - Settings page: "+ Key" on an unwatched Companion connection asks which group key to put it in when the Status page has no free spot (it used to make a key nobody could see); the connection field of a check suggests Companion's connection names. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+14
-2
@@ -420,6 +420,9 @@
|
||||
const c = cfg(), t = c.tiles[i];
|
||||
const k = await api("/api/keys");
|
||||
const kt = k.tiles.find((x) => x.id === t.id) || { says: [], holding: "", checks: [] };
|
||||
// A Companion connection is picked from the ones Companion has (typing still works).
|
||||
const cc = editing() ? await api("/api/companion").catch(() => ({})) : {};
|
||||
const connList = `<datalist id="connlist">${(cc.connections || []).map((r) => `<option value="${esc(r.label)}">${esc(r.module || "")}</option>`).join("")}</datalist>`;
|
||||
const fixOptions = (cur) => `<option value="">none</option><option value="restart-connection" ${cur === "restart-connection" ? "selected" : ""}>reconnect its Companion connection</option><option value="dante-auto" ${cur === "dante-auto" ? "selected" : ""}>Dante auto (PoE port or the Dante module)</option>${Object.entries(c.fixes).map(([id, f]) => `<option value="${esc(id)}" ${cur === id ? "selected" : ""}>${esc(f.short || id)} – ${esc(f.label || "")}</option>`).join("")}`;
|
||||
const short = (text, n) => { text = String(text || ""); return text.length > n ? text.slice(0, n - 1) + "…" : text; };
|
||||
let lastQ = null;
|
||||
@@ -432,7 +435,9 @@
|
||||
const summary = `<summary><b>${what}</b>${hint(sentence)}</summary>`;
|
||||
if (!editing()) return `${header}<details class="chk">${summary}<p class="small">${esc(sentence)}</p></details>`;
|
||||
const base = `tiles.${i}.checks.${j}.`;
|
||||
let fields = (spec.fields || []).filter((f) => !["fix", "type", "template", "params"].includes(f)).map((f) => inputHtml(base + f, F("tiles[].checks[]." + f), chk[f])).join("");
|
||||
let fields = (spec.fields || []).filter((f) => !["fix", "type", "template", "params"].includes(f)).map((f) => f === "conn"
|
||||
? inputHtml(base + f, F("tiles[].checks[]." + f), chk[f], connList).replace("<input ", '<input list="connlist" ')
|
||||
: inputHtml(base + f, F("tiles[].checks[]." + f), chk[f])).join("");
|
||||
if (chk.type === "remote") {
|
||||
const ctpls = state.builders.checks.concat([{ name: "custom", words: "Custom command (typed by hand)", params: [] }]);
|
||||
const ctName = chk.template || "custom", ct = ctpls.find((x) => x.name === ctName);
|
||||
@@ -1013,7 +1018,14 @@
|
||||
for (const b of main.querySelectorAll("[data-oremove]")) b.onclick = () => confirmBox(`Remove the ${b.dataset.oremove} outlet from the list? Fixes that use it stop working.`, "Remove", async () => { try { await post("/api/outlets", { name: b.dataset.oremove, remove: true }); route(); } catch (e) { alertBox(e.message); } });
|
||||
for (const td of main.querySelectorAll("[id^='ost-']")) api("/api/outlets/status?name=" + encodeURIComponent(td.id.slice(4))).then((r) => { td.innerHTML = r.ok ? `<span class="chip ${r.on ? "ok" : ""}">${r.on ? "on" : "off"}</span>` : `<span class="muted" data-hint="${esc(r.error)}">?</span>`; }).catch(() => {});
|
||||
for (const m of main.querySelectorAll("[data-map]")) m.onchange = () => { if (!m.value || !ensureDraft()) return; const [kind, name] = m.dataset.map.split("|"); (kind === "conn" ? renameConn : renameDante)(name, m.value); saveDraft(); route(); };
|
||||
for (const b of main.querySelectorAll("[data-addconn]")) b.onclick = () => { const conn = b.dataset.addconn; if (!ensureDraft()) return; const d = state.draft.config; let id = slug(conn) || "key", n = 2; while (d.tiles.some((t) => t.id === id)) id = slug(conn) + "_" + n++; const t = { id, label: conn.toUpperCase().replace(/[_-]+/g, " ").slice(0, 10).trim(), checks: [{ type: "conn", conn, fix: "restart-connection" }] }; const pos = firstEmpty(d, "status"); if (pos) t.pos = pos; d.tiles.push(t); saveDraft(); location.hash = "#keys/" + id; };
|
||||
for (const b of main.querySelectorAll("[data-addconn]")) b.onclick = () => { const conn = b.dataset.addconn; if (!ensureDraft()) return; const d = state.draft.config; let id = slug(conn) || "key", n = 2; while (d.tiles.some((t) => t.id === id)) id = slug(conn) + "_" + n++; const t = { id, label: conn.toUpperCase().replace(/[_-]+/g, " ").slice(0, 10).trim(), checks: [{ type: "conn", conn, fix: "restart-connection" }] }; const pos = firstEmpty(d, "status");
|
||||
if (pos) { t.pos = pos; d.tiles.push(t); saveDraft(); location.hash = "#keys/" + id; return; }
|
||||
// The Status page is full: put it inside a group key, where it shows and a hold on the group fixes it.
|
||||
const groups = d.tiles.filter((g) => g.members);
|
||||
dialog(`<h3>No free spot on the Status page</h3><p class="small">Put ${esc(conn)} inside a group key: its problems show on that key, and holding the key reconnects it.</p><select id="ngroup">${groups.map((g) => `<option value="${esc(g.id)}">${esc(g.label)} (${esc(g.members.join(", "))})</option>`).join("")}</select><div class="row"><button class="primary" id="dok">Add</button><button id="dcancel">Cancel</button></div>`, (bx) => {
|
||||
bx.querySelector("#dcancel").onclick = closeDialog;
|
||||
bx.querySelector("#dok").onclick = () => { const g = d.tiles.find((x) => x.id === bx.querySelector("#ngroup").value); d.tiles.push(t); if (g) g.members.push(id); saveDraft(); closeDialog(); location.hash = "#keys/" + id; };
|
||||
}); };
|
||||
for (const cb of main.querySelectorAll("[data-autofix]")) cb.onchange = () => { if (!ensureDraft()) return; const d = state.draft.config, id = cb.dataset.autofix, f = d.fixes[id]; const set = new Set(d.auto_fix.fixes || []); if (cb.checked) { set.add(id); if (closes(f)) f.restart_ok = true; if (f.never_auto) delete f.never_auto; } else set.delete(id); setPath("auto_fix.fixes", [...set]); };
|
||||
for (const b of main.querySelectorAll("[data-rmcheck]")) b.onclick = () => confirmBox("Remove this MIDI link from its key?", "Remove", () => { if (!ensureDraft()) return; const [tid, j] = b.dataset.rmcheck.split("|"); const t = state.draft.config.tiles.find((x) => x.id === tid); t.checks.splice(+j, 1); saveDraft(); route(); });
|
||||
const ds = q("#decksave"); if (ds) ds.onclick = () => applyDecks(main);
|
||||
|
||||
Reference in New Issue
Block a user