feat(scenes): loop the ambient preview at 2x by default#44
Conversation
The preview shipped locked to 1x on the theory that a viewer's saved rate is how fast they want to learn, not how fast a teaser should move, and that a faster pass would desync the stage: clock-driven phase logic racing ahead while wall-time transitions stayed at their authored speed. That second half is wrong. Scenes compute everything from the sequence clock, deliberately, because the render path drives them under a fake clock and wall-time CSS transitions either fail to progress or snap to the end under it. So the whole stage scales cleanly with the rate and a faster loop is not visually broken, just faster. What remained was taste, and the livelier read wins: double speed also covers the window in half the time, so the player settles in half as long. `preview` grows an optional `rate` for callers who want a different pace. It stays the loop's own rate rather than the viewer's either way, and theirs is still restored on the hand-back. A zero, negative or non-finite rate falls back to the default instead of freezing the clock at the first frame, which the grace timer would otherwise read as refused autoplay and settle.
📝 WalkthroughWalkthroughAmbient preview playback now supports configurable rates, defaults invalid values safely, applies the preview rate independently from the viewer rate, and restores the viewer rate on hand-back. Tests cover these behaviors, and a minor changeset documents the update. ChangesAmbient preview rate control
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
kino | 0ac9d57 | Commit Preview URL Branch Preview URL |
Jul 25 2026, 10:11 PM |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/scenes/provider.test.ts (1)
1201-1211: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winCover both infinity values in the invalid-rate test.
The normalization contract rejects every non-finite rate, but this test only exercises
NaN. AddInfinityand-Infinityso either case cannot regress unnoticed.Suggested test update
- for (const rate of [0, -1, Number.NaN]) { + for (const rate of [0, -1, Number.NaN, Infinity, -Infinity]) {🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/scenes/provider.test.ts` around lines 1201 - 1211, Extend the invalid-rate cases in the test “a rate that would stall the loop falls back to the default” to include both Infinity and -Infinity alongside the existing values. Keep the same mountPreviewing setup and assertion that each non-finite rate posts kino:setRate with the default rate of 2.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@src/scenes/provider.test.ts`:
- Around line 1201-1211: Extend the invalid-rate cases in the test “a rate that
would stall the loop falls back to the default” to include both Infinity and
-Infinity alongside the existing values. Keep the same mountPreviewing setup and
assertion that each non-finite rate posts kino:setRate with the default rate of
2.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: d4f4cdce-6e20-47e6-a48a-e1e16ca0c9b0
📒 Files selected for processing (3)
.changeset/loud-eels-argue.mdsrc/scenes/provider.test.tssrc/scenes/provider.ts
Follow-up to #42.
Why
The preview shipped locked to 1x on two arguments. One was taste: a viewer's saved rate is how fast they want to learn, not how fast a teaser should move. The other was technical, and it was wrong.
I assumed a faster loop would desync the stage, with clock-driven phase logic racing ahead while wall-time Motion transitions stayed at their authored speed. Scenes don't work that way. They compute everything from the sequence clock on purpose, because the render path drives them under a fake clock. From
GrowIn:So the whole stage scales cleanly with
playbackRate. A faster loop is not visually broken, just faster.With the technical objection gone, the livelier read wins. Double speed also covers the window in half the time, so with the default two cycles a 25s window settles the player in ~25s instead of ~50s.
What
previewgrows an optionalratefor callers who want a different pace.Testing
234 pass (3 changed or new), plus typecheck, lint, format and build.
Covered: the loop runs at 2x while the viewer sits at 1.2x and gets 1.2x back on the hand-back; an explicit
rateoverrides the default;0,-1andNaNeach fall back to 2x.Summary by CodeRabbit
New Features
Bug Fixes