commit ad7f7bbebdfefd43b098c19754ee178525a974b7
parent 801fd2d675000dfca1823098b6b6806188dbb9e6
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date: Thu, 1 Oct 2026 01:37:46 -0400
report-to-video: a deck that switches posts off is not held to the posts column's fit; embedFn's note sits above embedFn
Review lows on c0bb74dd.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Diffstat:
3 files changed, 18 insertions(+), 15 deletions(-)
diff --git a/umtool/report-to-video/chrome-posts.mjs b/umtool/report-to-video/chrome-posts.mjs
@@ -64,6 +64,18 @@ export function windowPosts(schedule, segment) {
}
/**
+ * A module function written into the page under a FIXED name. The page calls
+ * it by that name, and `fn.toString()` alone would declare whatever name the
+ * function has here -- which a bundler minifying server code renames (umtool's
+ * production build turned `postsCues` into `d`, and the page then threw a
+ * ReferenceError and drew nothing). As a named const of a parenthesised
+ * function expression, the page's name never depends on the module's.
+ */
+export function embedFn(name, fn) {
+ return `const ${name} = (${fn.toString()});`;
+}
+
+/**
* Everything the posts timeline does, as data. PURE and SELF-CONTAINED: the
* page carries this function's own source text and calls it with the heights
* it measured, so it may reference nothing outside its own body.
@@ -79,18 +91,6 @@ export function windowPosts(schedule, segment) {
* @returns {{ tops: number[], init: Record<string, object>,
* cues: Array<{ k: string, at: number, dur: number, from: object, to: object, ease: string, why: string }> }}
*/
-/**
- * A module function written into the page under a FIXED name. The page calls
- * it by that name, and `fn.toString()` alone would declare whatever name the
- * function has here -- which a bundler minifying server code renames (umtool's
- * production build turned `postsCues` into `d`, and the page then threw a
- * ReferenceError and drew nothing). As a named const of a parenthesised
- * function expression, the page's name never depends on the module's.
- */
-export function embedFn(name, fn) {
- return `const ${name} = (${fn.toString()});`;
-}
-
export function postsCues({ posts, heights, column, gap = 14, enter = 0.35, slide = 0.35, rise = 18 }) {
const R = (v) => Math.round(v * 10000) / 10000;
const MIN = 0.001;
diff --git a/umtool/report-to-video/deck.mjs b/umtool/report-to-video/deck.mjs
@@ -193,9 +193,10 @@ export function validateChrome(chrome, render = {}) {
// make the setting lie about what was drawn.
if (!errors.length) {
const g = deckGeometry({ ...render, chrome });
- // Only a deck that sets `posts` is held to the column's fit here; one with
- // posts on the defaults is checked by validatePosts, which sees the posts.
- if (d.posts !== undefined) errors.push(...postsFitErrors({ ...render, chrome }));
+ // Only a deck that sets `posts` and draws them is held to the column's fit
+ // here; one with posts on the defaults is checked by validatePosts, which
+ // sees the posts.
+ if (d.posts !== undefined && resolveDeck({ chrome }).posts.show) errors.push(...postsFitErrors({ ...render, chrome }));
const room = g.H - g.deck.height;
if (g.footage.height > room) {
const max = Math.floor((room / g.H) * 1000) / 1000;
diff --git a/umtool/report-to-video/deck.test.mjs b/umtool/report-to-video/deck.test.mjs
@@ -363,4 +363,6 @@ test("posts fit: a deck without posts is never refused for the column; drawn pos
assert.deepEqual(validatePosts([POST("p", "2024-01-01")], CLIPS), []);
// A deck that SETS posts is still held to the fit by validateChrome.
assert.match(validateChrome({ ...CHROME, deck: { footageScale: 0.5, posts: { width: 600 } } }, narrow).join(" "), /does not fit/);
+ // ...unless it switches them off.
+ assert.deepEqual(validateChrome({ ...CHROME, deck: { footageScale: 0.5, posts: { show: false } } }, narrow), []);
});