feat(voice): render the waveform on playback with click/drag/keyboard scrubbing
Voice messages carry an MSC1767 waveform (org.matrix.msc1767.audio.waveform) and the recorder draws a live one, but AudioContent playback only showed a plain seek bar. Now the player renders the waveform as bars that fill with the accent (TDS green under Lotus Terminal) as the clip plays, and the waveform itself is the seek control — click, drag, or keyboard (arrows +/-5s, Home/End) with role=slider + ARIA value text. - AudioContent: new optional "waveform" prop + a WaveformSeek sub-component (downsamples to 48 bars, mirrors the recorder's bar styling); falls back to the plain Range seek bar when there's no waveform. - Threaded through MAudio (RenderAudioContentProps) so timeline voice messages get it automatically; the Media Gallery Audio tab passes it directly. Improves both the timeline and the new gallery Audio tab at once. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -908,6 +908,9 @@ export function MediaGallery({ room, onClose }: MediaGalleryProps) {
|
||||
// audio/ogg) so the decrypted blob actually plays.
|
||||
const mimeType = getBlobSafeMimeType(c.info?.mimetype ?? 'audio/ogg');
|
||||
const filename = body.includes('.') ? body : `${body}.${mimeTypeToExt(mimeType)}`;
|
||||
const waveform = (
|
||||
c as unknown as { 'org.matrix.msc1767.audio'?: { waveform?: number[] } }
|
||||
)['org.matrix.msc1767.audio']?.waveform;
|
||||
return (
|
||||
<Box
|
||||
key={mEvent.getId()}
|
||||
@@ -956,6 +959,7 @@ export function MediaGallery({ room, onClose }: MediaGalleryProps) {
|
||||
url={url}
|
||||
info={c.info ?? {}}
|
||||
encInfo={c.file}
|
||||
waveform={waveform}
|
||||
renderMediaControl={(p) => <MediaControl {...p} />}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
Reference in New Issue
Block a user