Add none image animation and fix browser-source scaling + test-alert reliability (#122, #124) #125

Merged
Gitchegumi merged 4 commits from fix/browser-source-scaling-and-image-none-animation-122-124 into main 2026-07-08 16:54:53 -05:00
Gitchegumi commented 2026-07-08 11:54:08 -05:00 (Migrated from github.com)

Resolves #122 and #124.

#122 — none option for image asset animations

Adds a none entrance-animation mode so image assets can render without any editor-applied animation layer. Already-animated assets (GIF/APNG/animated WebP) now play exactly as provided instead of being overridden by an editor entrance animation.

  • Added none to the animation.in union and to the inspector's In animation dropdown.
  • buildAnimationStyle returns null for none, so the editor stage and browser-source runtime render the element statically and let the source file animate on its own.
  • Treated as a valid, saved value (round-trips through save/load), distinct from an unset value which still defaults to fade — so existing saved alerts without an animation are unaffected.

#124 — browser-source scaling & test-alert reliability

  • Viewport scaling (problems 1 & 2): the fixed-size stage is now wrapped in a full-viewport container and scaled via a CSS transform computed from the window size, preserving the canvas aspect ratio. The browser source matches the editor composition and fits windows smaller or larger than the configured canvas instead of clipping. OBS sources sized to the exact canvas render at scale 1 (unchanged).
  • Delivery reliability (problem 3): the SSE route now emits a periodic heartbeat so idle overlay connections aren't silently dropped, and the client EventSource no longer force-closes on transient errors so it can auto-reconnect. Redis pub/sub already broadcasts to every subscriber; these changes keep each client subscribed so a test alert reaches all overlays (OBS + regular windows), and avoid the reconnect churn that could trip the per-IP stream rate limit when several overlays are open.
  • Randomized test data (problem 4): test alerts now use a randomized viewer name and tip amount so variable substitution can be validated with realistic variation each run.

Testing

  • pnpm --filter @multi-stream-alerts/web typecheck ✅
  • pnpm --filter @multi-stream-alerts/web test — 197 passing (added coverage for buildAnimationStyle returning null on none) ✅

🤖 Generated with Claude Code

Resolves #122 and #124. ## #122 — `none` option for image asset animations Adds a `none` entrance-animation mode so image assets can render without any editor-applied animation layer. Already-animated assets (GIF/APNG/animated WebP) now play exactly as provided instead of being overridden by an editor entrance animation. - Added `none` to the `animation.in` union and to the inspector's **In** animation dropdown. - `buildAnimationStyle` returns `null` for `none`, so the editor stage and browser-source runtime render the element statically and let the source file animate on its own. - Treated as a valid, saved value (round-trips through save/load), distinct from an unset value which still defaults to `fade` — so existing saved alerts without an animation are unaffected. ## #124 — browser-source scaling & test-alert reliability - **Viewport scaling (problems 1 & 2):** the fixed-size stage is now wrapped in a full-viewport container and scaled via a CSS transform computed from the window size, preserving the canvas aspect ratio. The browser source matches the editor composition and fits windows smaller or larger than the configured canvas instead of clipping. OBS sources sized to the exact canvas render at scale `1` (unchanged). - **Delivery reliability (problem 3):** the SSE route now emits a periodic heartbeat so idle overlay connections aren't silently dropped, and the client `EventSource` no longer force-closes on transient errors so it can auto-reconnect. Redis pub/sub already broadcasts to every subscriber; these changes keep each client subscribed so a test alert reaches all overlays (OBS + regular windows), and avoid the reconnect churn that could trip the per-IP stream rate limit when several overlays are open. - **Randomized test data (problem 4):** test alerts now use a randomized viewer name and tip amount so variable substitution can be validated with realistic variation each run. ## Testing - `pnpm --filter @multi-stream-alerts/web typecheck` ✅ - `pnpm --filter @multi-stream-alerts/web test` — 197 passing (added coverage for `buildAnimationStyle` returning `null` on `none`) ✅ 🤖 Generated with [Claude Code](https://claude.com/claude-code)
PorteGumi (Migrated from github.com) approved these changes 2026-07-08 16:34:51 -05:00
PorteGumi (Migrated from github.com) left a comment

Approving. Resolves #122 and #124.

#122 (none animation): Clean addition. animation.in union gets 'none', buildAnimationStyle returns null for it, inspector dropdown includes it as the first option. Already-animated assets (GIF/WebP) now play untouched instead of being overridden by an editor entrance animation. Round-trips as a saved value, distinct from unset which still defaults to fade.

#124 (scaling + reliability):

  • Viewport scaling: OverlayClient computes scale = min(window.innerWidth/canvasWidth, window.innerHeight/canvasHeight) on resize. Stage wrapped in .overlay-viewport (fixed, full-viewport) with transform: scale(). OBS at exact canvas size gets scale=1. Correct approach.
  • SSE heartbeat: 15-second : ping comments keep idle connections alive. Properly cleaned up on disconnect. Good fix for proxies/load balancers that drop idle SSE.
  • EventSource: no longer force-closes on error — lets the browser auto-reconnect natively. Only logs when readyState === CLOSED. Prevents the silent disconnection + reconnect churn that could trip rate limits.
  • Randomized test data: 12 sample viewer names, random tip amounts $1-$100. Good for validating variable substitution.

Dead code removal: AlertCatalogManager.tsx (778 lines), ManualAlertForm.tsx, CanvasWorkspace.tsx, and ~350 lines of dead CSS from retired overlay editor. No remaining references. Clean.

196/196 tests pass, all 11 CI checks green.

Approving. Resolves #122 and #124. #122 (none animation): Clean addition. `animation.in` union gets `'none'`, `buildAnimationStyle` returns `null` for it, inspector dropdown includes it as the first option. Already-animated assets (GIF/WebP) now play untouched instead of being overridden by an editor entrance animation. Round-trips as a saved value, distinct from unset which still defaults to `fade`. #124 (scaling + reliability): - Viewport scaling: `OverlayClient` computes `scale = min(window.innerWidth/canvasWidth, window.innerHeight/canvasHeight)` on resize. Stage wrapped in `.overlay-viewport` (fixed, full-viewport) with `transform: scale()`. OBS at exact canvas size gets scale=1. Correct approach. - SSE heartbeat: 15-second `: ping` comments keep idle connections alive. Properly cleaned up on disconnect. Good fix for proxies/load balancers that drop idle SSE. - EventSource: no longer force-closes on error — lets the browser auto-reconnect natively. Only logs when `readyState === CLOSED`. Prevents the silent disconnection + reconnect churn that could trip rate limits. - Randomized test data: 12 sample viewer names, random tip amounts $1-$100. Good for validating variable substitution. Dead code removal: `AlertCatalogManager.tsx` (778 lines), `ManualAlertForm.tsx`, `CanvasWorkspace.tsx`, and ~350 lines of dead CSS from retired overlay editor. No remaining references. Clean. 196/196 tests pass, all 11 CI checks green.
Sign in to join this conversation.
No description provided.