commit 1f62103f1c425a358b391d61c6a675d0f3ce27c0
parent f64e77db6b491f26fa391a1c79fa20474d69a008
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date: Sun, 4 Oct 2026 16:21:32 -0400
umtool: the On-screen settings form gains qr.links (site | original), a deck save carries render.chrome.factcheck through instead of dropping it, and the deck's JSDoc types its new options (deckLayout's tally, deckQrUrl's links/meta, stampGeometry's feed)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Diffstat:
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/umtool/components/projects/OnscreenSection.tsx b/umtool/components/projects/OnscreenSection.tsx
@@ -517,7 +517,7 @@ type DeckSettings = {
pip: { spacing: string; size: number; activeSize: number };
title: { size: number; maxChars: number };
subtitle: { parts: "auto" | string[]; dateFormat: string };
- qr: { show: boolean; size: number };
+ qr: { show: boolean; size: number; links: string };
overCards: string;
motion: { out: number; in: number; pip: number };
posts: {
@@ -580,6 +580,7 @@ const GROUPS: { name: string; fields: Field[] }[] = [
fields: [
{ key: "qr.show", label: "show", kind: "bool", hint: "off drops every clip's QR" },
{ key: "qr.size", label: "size", kind: "num", hint: "px, 80–380 and at most height − 20" },
+ { key: "qr.links", label: "links", kind: "select", options: ["site", "original"], hint: "site: each clip's QR opens the archive at the clip; original: its source page — YouTube at the clip's second, a Rumble page, an X post. A clip's citeUrl wins either way" },
],
},
{
@@ -1045,6 +1046,9 @@ export default function OnscreenSection({
engine: (doc.chrome?.engine as string) ?? "hyperframes",
layout: (doc.chrome?.layout as string) ?? "deck",
deck: deckOf(form, doc.defaults),
+ // The fact-check settings are the manifest's (this form does not edit
+ // them): carried through as saved, never dropped by a deck save.
+ ...(doc.chrome?.factcheck !== undefined ? { factcheck: doc.chrome.factcheck } : {}),
};
const ok = await putChrome(chrome);
if (!ok) return;
diff --git a/umtool/report-to-video/deck.mjs b/umtool/report-to-video/deck.mjs
@@ -337,6 +337,9 @@ export function deckGeometry(render) {
* `tally` is the fact-check tally's verdicts (factcheck.mjs `tallyOf`), or
* null for none: with one, the tally takes a block of cells at one end of the
* text column (`factcheck.tally.position`) and the text keeps the rest.
+ *
+ * @param {any} render
+ * @param {{ tally?: string[] | null }} [opts]
*/
export function deckLayout(render, { tally = null } = {}) {
const { W, deck: rect } = deckGeometry(render);
@@ -535,6 +538,10 @@ export function deckText(entry, meta, provenance, deck, multiChannel) {
* links its record's own page instead (`meta.webpageUrl`, factcheck.mjs
* `originalUrlAt`: YouTube at the clip's start, a Rumble page or an X post
* as-is) -- or the site link still, when its record names none.
+ *
+ * @param {any} entry
+ * @param {any} [provenance]
+ * @param {{ links?: string, meta?: { webpageUrl?: string | null } | null }} [opts]
*/
export function deckQrUrl(entry, provenance = {}, { links = DECK_DEFAULTS.qr.links, meta = null } = {}) {
if (entry.type === "clip") {
@@ -1133,6 +1140,8 @@ export function feedGeometry(render) {
* its edges. 560×200 at 1920 wide, scaled with the frame; the stamp is drawn
* tilted inside it with room to spare.
*
+ * @param {any} render
+ * @param {{ feed?: boolean }} [opts]
* @returns {{ x: number, y: number, width: number, height: number }}
*/
export function stampGeometry(render, { feed = false } = {}) {