Files
buzz/desktop
Matt Toohey cc82626b53 fix(desktop): hand the media session to a video that is still playing
Review follow-up to 3d94c0e. Ownership was last-claim-wins, but release
cleared the session outright for the owner without considering that an
earlier claimant might still be audible. Nothing in the app pauses one
player when another starts, so two timeline videos can play at once: play
A, play B, then let B unmount (scrolled out of the virtualized window, or
its overlay closed). `releaseMediaSession(B)` set `metadata = null` and
`playbackState = "none"` while A was still making noise, and A could not
re-publish — `markMediaSessionPaused(A)` no-oped with `sessionOwner` back
to null. Telling macOS there is no session while audio plays is exactly the
state where the hardware key stops reaching the still-playing element, so
this was worse than stale metadata.

Claims now go into an ordered registry alongside the metadata each
published, and losing ownership looks for a successor: the most recently
claimed element that is still unpaused takes the session over, and it is
cleared only when nothing else is audible. The owner *pausing* takes the
same path — reporting "paused" over an audible sibling is the same lie in a
milder form. Claimants that left the document without releasing are dropped
during that scan, so the registry's strong keys cannot outlive the elements
if some future caller claims without `useReleasingVideoRef`.

Also makes the release-ordering test a real guard. It recorded
`video.currentTime`, which is 0 in jsdom either way, so moving `onRelease`
below `releaseVideoElement` left it green; it now records the source
attribute, which reads back null once the release has detached it.

## Validation

- `pnpm check`, `pnpm typecheck`, `pnpm test` (4961 desktop unit tests; the
  two `biome` warnings are pre-existing, in an unrelated E2E spec)
- Mutation-checked the three new/changed tests against the old behaviour:
  clearing unconditionally fails both handover tests, and running
  `onRelease` after the detach fails the ordering test
- Not covered: MediaRemote routing stays invisible to jsdom, so the
  outstanding manual macOS pass now also wants the two-video case — play
  one chat video, play a second, scroll the second away, and confirm the
  hardware key still controls the first rather than jumping back to Music

Signed-off-by: Matt Toohey <contact@matttoohey.com>
2026-09-02 15:13:34 +10:00
..
2026-03-09 13:02:11 -07:00
2026-06-11 15:06:24 +00:00
2026-03-09 13:02:11 -07:00

Buzz

Desktop chat shell with:

  • Tauri + React + TypeScript + Vite
  • Tailwind CSS
  • shadcn/ui-ready shared components
  • Biome (lint/format/check)
  • Feature-driven frontend structure

Scripts

  • pnpm dev - run the web frontend
  • pnpm tauri dev - run the desktop app
  • pnpm build - typecheck and build frontend
  • pnpm typecheck - TypeScript checks
  • pnpm lint - Biome lint
  • pnpm format - Biome format (write)
  • pnpm check - Biome check

Structure

  • src/shared - reusable app-wide code (ui, lib, styles)
  • src/features - feature modules (vertical slices)
  • src/app - top-level app composition