({ onClick, warnWhenSpeakingWhileMuted, ...rest })
| 16 | warnWhenSpeakingWhileMuted?: boolean |
| 17 | } |
| 18 | > = ({ onClick, warnWhenSpeakingWhileMuted, ...rest }) => { |
| 19 | const { |
| 20 | userMedia: { |
| 21 | turnMicOn, |
| 22 | turnMicOff, |
| 23 | audioEnabled, |
| 24 | audioUnavailableReason, |
| 25 | audioMonitorStreamTrack, |
| 26 | }, |
| 27 | } = useRoomContext() |
| 28 | |
| 29 | const toggle = () => { |
| 30 | audioEnabled ? turnMicOff() : turnMicOn() |
| 31 | } |
| 32 | |
| 33 | useKey((e) => { |
| 34 | if (e.key === 'd' && e.metaKey) { |
| 35 | e.preventDefault() |
| 36 | return true |
| 37 | } |
| 38 | return false |
| 39 | }, toggle) |
| 40 | |
| 41 | const isSpeaking = useIsSpeaking(audioMonitorStreamTrack) |
| 42 | |
| 43 | const audioUnavailableMessage = audioUnavailableReason |
| 44 | ? errorMessageMap[audioUnavailableReason] |
| 45 | : null |
| 46 | |
| 47 | return ( |
| 48 | <> |
| 49 | <Tooltip |
| 50 | content={ |
| 51 | audioUnavailableMessage ?? |
| 52 | `Turn mic ${audioEnabled ? 'off' : 'on'} (${metaKey}D)` |
| 53 | } |
| 54 | > |
| 55 | <Button |
| 56 | displayType={audioEnabled ? 'secondary' : 'danger'} |
| 57 | disabled={!!audioUnavailableMessage} |
| 58 | onClick={(e) => { |
| 59 | toggle() |
| 60 | onClick && onClick(e) |
| 61 | }} |
| 62 | {...rest} |
| 63 | > |
| 64 | <VisuallyHidden> |
| 65 | {audioEnabled ? 'Turn mic off' : 'Turn mic on'} |
| 66 | </VisuallyHidden> |
| 67 | <Icon type={audioEnabled ? 'micOn' : 'micOff'} /> |
| 68 | </Button> |
| 69 | </Tooltip> |
| 70 | {isSpeaking && !audioEnabled && warnWhenSpeakingWhileMuted && ( |
| 71 | <Toast.Root |
| 72 | className="flex items-center gap-3 text-sm" |
| 73 | open |
| 74 | type="foreground" |
| 75 | > |
nothing calls this directly
no test coverage detected