Play the whole season on the virtual strip (#151) #172

Merged
claude-bot merged 1 commit from feat/151-season-preview into main 2026-09-26 10:03:15 +00:00
Collaborator

Closes #151.

Why

Reviewing a season meant opening schemes one at a time. Nothing answered "what will the house look like over the next two months?"

What

GET /api/v1/schemes/for-range?start=&days= (60 by default, capped at 120, viewer-accessible) loops over #149's plan_for_range and adds no resolution of its own.

  • Each night's segments_state comes from plan.wled_state, so the preview shows what the on job will actually push:
    • An unapproved night that will go dark previews dark.
    • A no-event default previews as that default.
    • Since #150, a flashing effect previews slowed or replaced, exactly as it will be pushed. flash_substitutions is included per night, and the caption notes it.
  • The scheme serialisation is shared with /schemes/for-date, so the two can't disagree.

The /season page is linked from a clapperboard icon in the header.

  • Controls: a strip per segment drawn with the existing colorAt renderer, Play (1 night/s, adjustable), a scrubber, ← / → and prev/next, and a caption.
  • Timeline: a day-coloured band under the strip. Its colour is the most-used colour slot, not an average, because red and green would average to mud.
  • Markers: dark and default nights use #149's markers, and link to that night in the review queue.
  • "Show the night": an optional, proportional sketch of fade-in, dim and off. It isn't a model of the schedule, and the docs say so.
  • Save as video: WebM via MediaRecorder, feature-detected.
  • prefers-reduced-motion: still swatches, with the same controls.

Refactor: canvas drawing moved to virtualStrip.ts / useVirtualStrip.ts. The side-panel preview and the season preview now draw the same way, and the side panel keeps #150's guard exactly as it is on main.

Verification (rebased onto main with #149, #150 and #164 in)

  • Backend: pytest 1052 passed, 27 of them for this feature. Every night is checked against plan_for_date across all 5 settings combinations, and every serialised scheme against for-date. Guard on/off cases use real Strobe at sx 255 and real Lightning. ruff and mypy are clean.
  • Frontend: lint (0 warnings), tsc, vitest (187 passed) and build.
  • E2E, run the CI way: 13/13. That covers opening /season directly (now possible because of #164), stepping and playing, and a marker link landing on the right night. It was also run once in demo mode, where the video export produced a .webm.

Found

Demo mode's showcase schemes are approved with no segments, so those nights preview unlit. The preview is reporting that accurately. Filed as #171.

🤖 Generated with Claude Code

Closes #151. ## Why Reviewing a season meant opening schemes one at a time. Nothing answered "what will the house look like over the next two months?" ## What **`GET /api/v1/schemes/for-range?start=&days=`** (60 by default, capped at 120, viewer-accessible) loops over #149's `plan_for_range` and adds **no resolution of its own.** - Each night's `segments_state` comes from `plan.wled_state`, so the preview shows what the on job will actually push: - An unapproved night that will go dark previews **dark**. - A no-event default previews as that default. - Since #150, a flashing effect previews **slowed or replaced**, exactly as it will be pushed. `flash_substitutions` is included per night, and the caption notes it. - The scheme serialisation is shared with `/schemes/for-date`, so the two can't disagree. **The `/season` page** is linked from a clapperboard icon in the header. - **Controls:** a strip per segment drawn with the existing `colorAt` renderer, Play (1 night/s, adjustable), a scrubber, ← / → and prev/next, and a caption. - **Timeline:** a day-coloured band under the strip. Its colour is the most-used colour slot, not an average, because red and green would average to mud. - **Markers:** dark and default nights use #149's markers, and link to that night in the review queue. - **"Show the night":** an optional, proportional sketch of fade-in, dim and off. It isn't a model of the schedule, and the docs say so. - **Save as video:** WebM via `MediaRecorder`, feature-detected. - **`prefers-reduced-motion`:** still swatches, with the same controls. **Refactor:** canvas drawing moved to `virtualStrip.ts` / `useVirtualStrip.ts`. The side-panel preview and the season preview now draw the same way, and the side panel keeps #150's guard exactly as it is on main. ## Verification (rebased onto `main` with #149, #150 and #164 in) - **Backend:** pytest 1052 passed, 27 of them for this feature. Every night is checked against `plan_for_date` across all 5 settings combinations, and every serialised scheme against `for-date`. Guard on/off cases use real Strobe at `sx` 255 and real Lightning. ruff and mypy are clean. - **Frontend:** lint (0 warnings), `tsc`, vitest (187 passed) and build. - **E2E, run the CI way:** 13/13. That covers opening `/season` directly (now possible because of #164), stepping and playing, and a marker link landing on the right night. It was also run once in demo mode, where the video export produced a `.webm`. ## Found Demo mode's showcase schemes are approved with no segments, so those nights preview unlit. The preview is reporting that accurately. Filed as #171. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Play the whole season on the virtual strip (#151)
All checks were successful
CI / Pre-commit hooks (pull_request) Successful in 1m29s
CI / Python lint & type-check (pull_request) Successful in 1m1s
CI / Dockerfile lint (pull_request) Successful in 8s
CI / Alembic migration check (pull_request) Successful in 1m11s
CI / Frontend lint, test & build (pull_request) Successful in 2m12s
CI / Python tests (pull_request) Successful in 6m1s
CI / Docker build, health smoke & E2E (pull_request) Successful in 2m4s
76a60c0041
A Season preview page plays the coming nights (60 by default, up to 120)
on the virtual strip, one a second, with speed, scrubbing and arrow-key
stepping. A band underneath colours each night by its main colour, dark
where nothing lights, and marks unapproved nights with the calendar's
dashed moon, linking to that night in the review queue. Optional
"show the night" envelope, WebM export where the browser supports it,
and still swatches under prefers-reduced-motion.

Backed by GET /schemes/for-range, built on day_plan.plan_for_range and
drawn from each plan's pushed wled_state, so unapproved-dark nights
preview dark and no-event nights preview as the default. Tests hold it
to plan_for_date on every night and to /schemes/for-date on the scheme.

The canvas drawing moves out of SchemeAnimationPreview into a shared
virtualStrip/useVirtualStrip so both previews draw LEDs identically.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude-bot deleted branch feat/151-season-preview 2026-09-26 10:03:17 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rbrooks/Iris-WLED!172
No description provided.