screentinker/server
Claude 47bda040a2 Re-render when a screen leaves a sync group or a video wall
Taking a display out of a sync group, or deleting the wall it belonged to, froze it on whatever was
playing. The clip looped forever and every later refresh took the "unchanged" branch, because the
element was attached, playing and un-errored — healthy by every check the player makes. Only a
reboot cleared it.

On the web player, reconcileAdvanceTimerForMode re-arms a solo timer for widgets and images but
skips video and YouTube, on the grounds that they "self-advance via their own end handlers". The
handler that is live at that moment, though, was built for the mode being left: a group-rendered
video was created with `loop = !!groupSync`, a wall-follower video with `isFollower` true, and both
are captured in the closure at render time. A looping element never fires `ended`, and a follower's
handler declines to advance — so nothing self-advances and nothing re-renders. It now re-renders
whenever the element on screen is still looping, rather than guessing which media types can look
after themselves.

Tizen had the same freeze by a different route. GroupSyncController.exit and WallController.exit
both call player.invalidate() for exactly this purpose, but invalidate only cleared the change
signature — and load() returns at the continuity check ("current item survives, just retarget the
index") before reaching any render, so the invalidate was a no-op. It now forces the next load to
re-render, which is what those call sites always intended. On Tizen this froze every item type, not
just video, because `single` skips the timer in all of the renderers.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uaeo9MvzKoyXuN6ZsbhtkL
2026-07-30 22:29:06 -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 Keep a workspace on schedules that outlive their device group 2026-07-30 20:53:21 -05:00
lib Apply a saved device snapshot only inside the workspace it was taken in 2026-07-30 20:56:59 -05:00
middleware Merge branch 'fix/recovery-grants' into release/auth-campaign 2026-07-26 16:22:59 -05:00
player Re-render when a screen leaves a sync group or a video wall 2026-07-30 22:29:06 -05:00
routes Make a content-only schedule actually put that content on the screen 2026-07-30 22:26:58 -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 Make a recurring schedule respect its start and end dates 2026-07-30 22:22:59 -05:00
test Make a content-only schedule actually put that content on the screen 2026-07-30 22:26:58 -05:00
ws Treat an empty device_info as "nothing new", not as "forget what you know" 2026-07-30 21:09:11 -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