Skip to content

Timeline plugin: playback controls - #242

Open
sandesh-sp wants to merge 4 commits into
feat/timeline-date-selectorfrom
feat/timeline-playback-controls
Open

Timeline plugin: playback controls#242
sandesh-sp wants to merge 4 commits into
feat/timeline-date-selectorfrom
feat/timeline-playback-controls

Conversation

@sandesh-sp

@sandesh-sp sandesh-sp commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

Replaces the playback placeholders with the real controls: skip to start/end, step back/forward, play/pause, and a button cycling the speed multiplier through 1x, 2x, 4x, 0.5x. Play and speed are hidden when a mission turns playback off.

Stack — merge in order, starting from the base:

  1. Timeline plugin: shell and component placeholders #239 shell and component placeholders → development
  2. Timeline plugin: timeline view #240 timeline view
  3. Timeline plugin: date selector #241 date selector
  4. Timeline plugin: playback controls #242 playback controls
  5. Timeline plugin: time mode control #243 time mode control

Replaces the playback placeholders with the real controls: skip to start
and end, step back and forward, play/pause, and a button that cycles the
speed multiplier through 1x, 2x, 4x and 0.5x. The play button and the
speed button are hidden when a mission turns playback off.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AgqjkZhQvfoBgdJtt9SSKS
- Name every icon-only button, expose play/pause through aria-pressed, and
  group the transport under a labelled role.
- Disable the step and skip buttons at the end of the range they move toward,
  so a button that cannot act now looks and reads as inert. The adapter clamps
  rather than dropping the step, so the buttons stay live until the boundary
  is actually reached.
- Restart the speed cycle from a value outside it, keeping the playback
  interval from being handed a zero or negative multiplier.
@sandesh-sp

Copy link
Copy Markdown
Collaborator Author

Review pass over the stack (#239#243). Pushed as 2221522, rebased on #239#241.

Worth flagging up front: the playback engine these controls drive lives in TimelineAdapter.tsx, which is only ever touched by #239 — so the three engine-side issues were fixed there and this PR carries the UI half.

In this PR

  • Icon-only buttons had no accessible name. Five transport buttons carried title alone. Each now has an aria-label, play/pause exposes state through aria-pressed, and the group is labelled.
  • Dead affordances at the range endpoints. handleStepForward/handleStepBackward dropped the step when it would overshoot rather than clamping, and the buttons were never disabled — so with currentTime within one step of an endpoint the button looked fully live and did nothing. The adapter now clamps (fixed in Timeline plugin: shell and component placeholders #239), and canStepForward/canStepBackward drive disabled here, so a button only reads as inert once the boundary is actually reached.
  • Speed cycle restarts from a value outside the list instead of returning undefined, so the interval can never be handed a zero or negative multiplier.

Fixed in #239 (engine side)

  • Play at the end of the range armed an interval that self-cancelled one tick later — the Pause icon showed for a full second at 1x with zero movement. Now rewinds to the start.
  • The setCurrentTime updater was impure, calling mmgisEmit('time:changeRequested') and setIsPlaying(false) from inside itself. The bus is synchronous mitt, so the emit ran timeInputChange → layer reload → re-entry into the same hook, from inside a state updater. Both now run in the interval body against refs.
  • That change also removed startTime/endTime from the interval's deps, so a core echo mid-playback no longer tears down and rebuilds the interval every tick.

On throttling: I looked at whether 4x playback hammers core too hard and concluded it doesn't — core's own TimeUI ships a 100ms interval on the identical path (TimeUI.js:1433), so this is strictly more conservative than the UI it sits alongside.

tsc --noEmit clean, 898 unit tests pass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant