ceskacan.
TR

State management / NoirWave

From audio events to a consistent player

The timeline, play button and full-screen view need to represent the same audio stream.

2 min read

The interface and actual behaviour

A button’s appearance cannot determine whether audio is really playing. The browser can load metadata, pause playback or reach the end of a track. Events from the audio engine therefore need to update the state used by the interface. NoirWave’s source excerpt shows that connection directly.

Move events into shared state

timeupdate updates the current position, loadedmetadata sets duration, and play and pause update playback state in Zustand. The ended event calls the next-track action. The interface is consequently informed by audio events as well as the user’s most recent button click.

More than one view

PlayerBar and FullscreenPlayer use the same store. This provides a foundation for avoiding separate versions of playback truth in each view. Scrubbing uses setProgress() to update audio.currentTime. Controls affect the audio element, while native events feed information back into shared state.

Boundaries to check

Track changes, seeking before metadata is ready, pauses and track endings are important boundaries. Tests for these boundaries can follow the event order: initial state, audio event and expected state in both views. This makes it easier to locate a mismatch in the audio layer or the interface.

Open the source excerpt ↗