Player design · 2026-09-23
Timestamped comments on a shared waveform
Comments on Soundfish albums pin to moments on the same full-track time axis the waveform, playhead, and seek surface use — so feedback lands where the music is. The design and mechanics behind it.
Feedback belongs on the wave
A comment that says “the drop at 1:23” asks the reader to do the alignment. Soundfish comments carry a track and a timestamp at write time, and they render as avatar markers on the same full-track time axis the waveform, seek surface, and playhead already share. The marker is the comment's address; the comment is the marker's content.
Choosing a marker seeks the playhead to that moment — the same behavior the timestamp button inside a discussion has — so reading feedback about a bar puts you in that bar.
Markers, previews, and the compose lane
Each marker carries the commenter's avatar; hovering or focusing it shows a preview card with the comment's first lines. Clicking empty space on the wave opens a compose lane pre-filled with that timestamp, so the natural gesture — point at the moment — is also the write path.
Discussion volume is bounded by design: at most three comments render initially, keeping the track queue reachable, with expansion and pagination behind them. Drafts survive playback changes and keep their track and time target, and a sign-in detour stashes the pending draft in session storage (not the account token) so it is waiting when you come back.
A player that respects the tab
Keyboard control covers space or k for play/pause, arrows for five-second seeks, c for the composer, and l for a heart. Media Session publishes full metadata — title, artist, artwork — plus transport handlers for play, pause, previous and next track, seek-to, and seek backward and forward, so lock screens and system media keys behave. While a track plays, the document title mirrors ▶ track · album and restores itself on pause or unmount.
The player is polite about resources too: engagement reads throttle refocus reloads, writes abort on a fifteen-second timeout, and the audio element requests only metadata until play.
Three modes, one model
The same AlbumView drives three honest modes. Public mode is the full surface — playback, counts, hearts, comments, share. Embed mode shows counts, markers, and a read-only three-comment preview, with interactive actions linking back to the album page; it also posts soundfish:resize and soundfish:location messages and honors a strictly validated soundfish:theme message from its host. Preview mode, used on the manage page, sends no engagement at all — no plays, hearts, comments, or sign-in — because the owner checking the page is not a listener.
- ?track=<slug> and &t=… restore a position once after hydration — never autoplay.
- Track selection rewrites the URL with history.replaceState; embeds report it to the host.
- Every engagement call goes to one same-origin route with credentials and zod-parsed responses.
The short version
The axis is the idea: one timeline that the listener, the playhead, and the feedback all agree on.