From a0fa8a0133b8f7d33a0af3936b98ef753dfa1f76 Mon Sep 17 00:00:00 2001 From: Matt Toohey Date: Mon, 17 Aug 2026 21:24:15 +1000 Subject: [PATCH] fix(desktop): name the composer video preview in Now Playing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Review follow-up to 3d94c0e. The composer attachment preview released the media session on unmount but never claimed it on play, so while a queued video played, Control Center showed either a bare Buzz entry or — since `navigator.mediaSession.metadata` is page-global — the stale title of a timeline video that had claimed the session earlier. `onPlay` now claims with the attachment's filename (falling back to the short-hash label the thumbnail already uses), and `onPause`/`onEnded` mark the session paused, matching the inline player and the review overlay. There is no channel subtitle: the attachment has not been posted yet, so there is nothing honest to put there. The owner-scoped release added in 3d94c0e already covers teardown, so this only closes the metadata gap. - `pnpm check`, `pnpm typecheck`, `pnpm test` (4958 desktop unit tests, all passing; the two `biome` warnings are pre-existing, in an unrelated E2E spec) - Not covered: same gap as the other two surfaces — the claim wiring is JSX event handlers over the already-tested `mediaSession` module, and this package has no precedent for rendering a motion + Radix component tree in a unit test. Control Center metadata is invisible to Playwright and jsdom, so the outstanding manual macOS pass now also wants: attach a video, open its composer preview, play it, and confirm Control Center shows that filename rather than a previously-played timeline video. Signed-off-by: Matt Toohey --- .../messages/ui/ComposerAttachments.tsx | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/desktop/src/features/messages/ui/ComposerAttachments.tsx b/desktop/src/features/messages/ui/ComposerAttachments.tsx index a0455116ec..b83dbcb8a7 100644 --- a/desktop/src/features/messages/ui/ComposerAttachments.tsx +++ b/desktop/src/features/messages/ui/ComposerAttachments.tsx @@ -30,7 +30,12 @@ import { AttachmentMedia, AttachmentTitle, } from "@/shared/ui/attachment"; -import { useReleasingVideoRef } from "@/shared/ui/mediaSession"; +import { + claimMediaSession, + markMediaSessionPaused, + type NowPlayingMetadata, + useReleasingVideoRef, +} from "@/shared/ui/mediaSession"; import { MODAL_BACKDROP_BLUR_CLASS } from "@/shared/ui/modalBackdrop"; import { Progress } from "@/shared/ui/progress"; import { Toggle } from "@/shared/ui/toggle"; @@ -293,6 +298,16 @@ const MediaAttachmentItem = React.forwardRef< ? rewriteRelayUrl(attachment.thumb) : undefined; + // `navigator.mediaSession.metadata` is page-global, so a preview that played + // without claiming would leave Control Center showing whatever timeline video + // published last. No channel subtitle here — the attachment isn't posted yet. + const mediaSessionMetadata = React.useMemo( + () => ({ + title: attachment.filename?.trim() || mediaLabel, + }), + [attachment.filename, mediaLabel], + ); + // Only Buzz-hosted uploads have a content hash. URL-only provider media // must remain externally hosted instead of being copied into storage by the // image editor's save path. @@ -442,6 +457,15 @@ const MediaAttachmentItem = React.forwardRef< "relative max-h-[90vh] max-w-[90vw] rounded-lg", isSpoilered && "blur-2xl brightness-75", )} + onEnded={(event) => + markMediaSessionPaused(event.currentTarget) + } + onPause={(event) => + markMediaSessionPaused(event.currentTarget) + } + onPlay={(event) => + claimMediaSession(event.currentTarget, mediaSessionMetadata) + } /> ) : (