Web player: re-render a widget whose content was edited

The signature fix was necessary but not sufficient, and only a browser showed it. The update arrived
and was applied — the console logged "Playlist changed, updating" and playlist[0].widget_rev held the
NEW revision — but the iframe on screen still carried the old one.

Two guards were swallowing it. Continuity keeps a surviving item playing and deliberately does not
re-render ("Just retarget the index pointer - no re-render, no interrupt"), and identity is
content/widget ID, which does not change when a widget is EDITED. So the edited widget counted as
surviving. And the fallback that would eventually notice does not apply either: a solo widget is
deliberately never re-rendered on a timer, because that would reset a directory board's scroll.

Between them the new revision sat in the playlist, unused, indefinitely.

Now a surviving WIDGET whose rev changed is re-rendered through the buffered swap — which builds the
new iframe hidden and reveals it on load, so it is flash-free by design and this costs nothing
visually. Non-widget items and unedited widgets are untouched, so the continuity behaviour that
guard exists for is intact.

Verified in headless Chrome driving the real player: paired, widget assigned, then edited with no
page reload and no restart. rev 1785460578 -> 1785460589 on the live iframe.

Also caught here: my first attempt called renderItem(), which does not exist — the console.log fired
and the exception ate the rest of the handler, which looked exactly like the fix not working. The
function is renderContent(item).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uaeo9MvzKoyXuN6ZsbhtkL
This commit is contained in:
Claude 2026-07-30 20:17:22 -05:00
parent 5c6e0325b1
commit e0bdd3b65c

View file

@ -1977,6 +1977,18 @@
if (stillThereIdx !== -1) {
currentIndex = stillThereIdx;
isPlaying = true;
// ...unless it is a WIDGET whose content was edited. Identity is content/widget id, and
// editing a widget does not change its id, so an edited widget "survives" and the
// re-render is skipped — which is exactly why an edit never reached the screen. The new
// revision sat in the playlist unused, because a solo widget deliberately never
// re-renders on a timer (that would reset a directory board's scroll). Re-render through
// the buffered swap, which is flash-free by design, so this costs nothing visually.
const oldItem = oldPlaylist[oldAnchorIdx];
const newItem = playlist[stillThereIdx];
if (newItem && newItem.widget_id && oldItem && (oldItem.widget_rev || 0) !== (newItem.widget_rev || 0)) {
console.log('Widget edited - re-rendering in place');
renderContent(newItem);
}
return;
}
}