Skip to content

Add deafen toggle to mute all incoming audio#3763

Draft
alisonjenkins wants to merge 6 commits intoelement-hq:livekitfrom
alisonjenkins:alisonjenkins/deafen-toggle
Draft

Add deafen toggle to mute all incoming audio#3763
alisonjenkins wants to merge 6 commits intoelement-hq:livekitfrom
alisonjenkins:alisonjenkins/deafen-toggle

Conversation

@alisonjenkins
Copy link

@alisonjenkins alisonjenkins commented Feb 28, 2026

Summary

  • Add deafen event type and DeafenReader for reading remote deafen state from Matrix room events
  • Add local deafen toggle with muteAllAudio$ integration to suppress all incoming audio
  • Thread deafened$ observable through CallViewModel and UserMediaViewModel for UI state
  • Add DeafenButton component and deafened indicator on participant tiles
  • Broadcast deafen state to other participants via ReactionsSenderProvider
  • Wire deafen button into the call toolbar with auto-mute mic on deafen (restores previous state on un-deafen), 'd' keyboard shortcut, and translation keys

Test plan

  • Verify deafen button appears in the call toolbar and toggles deafen state
  • Confirm all incoming audio is silenced when deafened
  • Test that microphone is auto-muted when deafening and restored to previous state on un-deafen
  • Verify mic toggle is disabled while deafened
  • Test 'd' keyboard shortcut toggles deafen
  • Confirm deafened indicator appears on the local participant's tile
  • Verify deafen state is broadcast to and visible by other participants

🤖 Generated with Claude Code

alisonjenkins and others added 6 commits February 28, 2026 07:49
Define ElementCallDeafenedKey ("io.element.call.deafened") and
DeafenedInfo type. Add DeafenReader class that listens for m.reaction
events with the deafen key on membership events, following the same
pattern as ReactionsReader for hand raises.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
DeafenModel provides a simple BehaviorSubject toggle for local deafen
state. MuteAllAudioModel now includes deafened$ as a third input to
muteAllAudio$, so deafening automatically mutes all incoming audio
renderers (LiveKit, call events, reactions).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add deafenedSubject$ parameter to createCallViewModel$ and expose
deafened$ on the CallViewModel interface. Map per-member deafen state
into BaseUserMediaViewModel so tiles can read it. Update test utilities
and SDK to pass the new parameter.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New DeafenButton in Button.tsx using HeadphonesSolidIcon /
HeadphonesOffSolidIcon from Compound. GridTile now subscribes to
vm.deafened$ and shows a HeadphonesOffSolidIcon in the name tag
when the participant is deafened.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Follow the toggleRaisedHand pattern: send an m.reaction event with
key io.element.call.deafened to announce deafen state, and redact
it to un-deafen. Expose toggleDeafened in the context so InCallView
can broadcast state changes to other participants.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
InCallView: instantiate DeafenReader, add DeafenButton to toolbar,
auto-mute mic on deafen (restore previous state on un-deafen), and
disable mic toggle while deafened. Add 'd' keyboard shortcut for
toggling deafen. Add translation keys for deafen/undeafen labels
and the deafened tile indicator.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant