screentinker/server
Claude 4cc750ba3a Text widgets: stop losing text off the bottom, and show an edit without an app restart
Two separate faults in the same widget, both reported on #234.

1. Text taller than the screen vanished in silence. renderText set overflow:hidden on the document
   with nothing able to scroll it, so anything past the bottom edge was simply gone: "Text goes to
   bottom and disappears. It dont fit."

   The content now gets a wrapper and an overflow mode:
     fit    (default) shrink until it fits — a NO-OP when the content already fits, so it rescues
            widgets that are currently losing text without changing ones that are fine
     scroll pan through it on a loop with a pause at each end, for content genuinely longer than a
            screen where shrinking would make it unreadable
     clip   the old behaviour, kept because a designer-positioned layout may deliberately run past
            the edge and must not be rescaled underneath its author

   Measuring runs after layout, after web fonts settle, and on resize — a rotation or a resized zone
   changes the answer, and fonts arriving late is the classic cause of a fit computed against the
   wrong height.

2. Editing a widget did not reach the screen until the app was restarted. The render endpoint serves
   live config, but the player deliberately keeps a widget's WebView while its URL is unchanged
   (re-navigating every duration is a visible flash and destroys widget state — a half-typed
   directory search, scroll position). Editing changes the content, not the id, so the URL never
   changed and the reuse check always hit.

   The widget's updated_at now travels to the player as widget_rev and goes into the render URL, so
   the URL differs exactly when the content differs — and only then, so the anti-flash reuse still
   holds for untouched widgets. The rev is refreshed at send time rather than read from the
   published snapshot, because a widget edit does not republish the playlist. Editing a widget also
   now pushes to the displays showing it, instead of notifying nothing at all.

859 server tests green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uaeo9MvzKoyXuN6ZsbhtkL
2026-07-30 19:44:12 -05:00
..
config fix(logging): gate CF-Connecting-IP on a Cloudflare peer, not any trusted proxy 2026-07-26 10:23:04 -05:00
db Serve a beta APK alongside the stable one, and let a display move between them 2026-07-30 19:12:46 -05:00
lib Serve a beta APK alongside the stable one, and let a display move between them 2026-07-30 19:12:46 -05:00
middleware Merge branch 'fix/recovery-grants' into release/auth-campaign 2026-07-26 16:22:59 -05:00
player Attribute a widget play to the widget that played 2026-07-28 19:06:56 -05:00
routes Text widgets: stop losing text off the bottom, and show an edit without an app restart 2026-07-30 19:44:12 -05:00
scripts fix(content+android): rotation-aware media — portrait upright on dashboard AND player (#170) (#172) 2026-07-12 22:05:11 -05:00
services Report zero event-loop lag when a window recorded no samples 2026-07-28 14:11:32 -05:00
test Serve a beta APK alongside the stable one, and let a display move between them 2026-07-30 19:12:46 -05:00
ws Text widgets: stop losing text off the bottom, and show an edit without an app restart 2026-07-30 19:44:12 -05:00
.gitignore feat(email): Microsoft Graph send + alert spam protection + preferences UI 2026-05-12 18:16:40 -05:00
config.js Add an operator override for self-update on MDM-managed panels 2026-07-28 23:07:30 -05:00
package-lock.json chore(release): v1.9.27 2026-07-30 19:16:55 -05:00
package.json chore(release): v1.9.27 2026-07-30 19:16:55 -05:00
server.js Serve a beta APK alongside the stable one, and let a display move between them 2026-07-30 19:12:46 -05:00
smoke-ui.js Keep the smoke test out of npm test, and update the lockfile 2026-07-28 20:34:34 -05:00
version.js chore(version): single-source VERSION, env-configurable data paths, bump tooling 2026-06-10 12:56:03 -05:00