feat(call): mic level meter on the mute button (#146)

While unmuted, the microphone button (call view and the bottom call bar)
shows three small green bars in the icon's corner driven by the fork's
io.lotus.mic_level (element-call v0.25.0-lotus.16), so you can see the mic is
actually picking you up. Nothing is drawn while muted or silent; the button's
label is unchanged (the bars are decorative).

Your own name no longer appears in the "… is speaking" line: that is now for
everyone else, and your voice is on the meter. Avatar speaking rings still
include you, and the "You're muted" talking-while-muted notice is unchanged.

Verified in a local call with a fake-tone mic: data-mic-level cycles 3/2/1
with the tone on both buttons, disappears on mute and returns on unmute; the
status line reads "bob is speaking..." only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
This commit is contained in:
Lotus CI
2026-09-25 12:09:34 -04:00
co-authored by Claude Opus 5.5
parent 75d55e861b
commit 3449338b3e
7 changed files with 123 additions and 11 deletions
+7 -2
View File
@@ -29,7 +29,7 @@ import {
SoundButton,
VideoButton,
} from './Controls';
import { CallEmbed, useCallControlState } from '../../plugins/call';
import { CallEmbed, useCallControlState, useCallMicLevel } from '../../plugins/call';
import { useSetting } from '../../state/hooks/settings';
import { settingsAtom } from '../../state/settings';
import { callEmbedAtom } from '../../state/callEmbed';
@@ -85,6 +85,7 @@ export function CallControls({ callEmbed }: CallControlsProps) {
const { microphone, video, sound, screenshare, spotlight, screenshareAudioMuted } =
useCallControlState(callEmbed.control);
const micLevel = useCallMicLevel(callEmbed);
const [cords, setCords] = useState<RectCords>();
const [shareConfirm, setShareConfirm] = useState(false);
@@ -200,7 +201,11 @@ export function CallControls({ callEmbed }: CallControlsProps) {
>
<Box alignItems="Center" gap="Inherit" grow="Yes" direction={compact ? 'Column' : 'Row'}>
<Box shrink="No" alignItems="Inherit" justifyContent="Inherit" gap="200">
<MicrophoneButton enabled={microphone} onToggle={handleMicrophoneToggle} />
<MicrophoneButton
enabled={microphone}
onToggle={handleMicrophoneToggle}
level={micLevel}
/>
<SoundButton enabled={sound} onToggle={() => callEmbed.control.toggleSound()} />
</Box>
{!compact && showVideoGroup && <ControlDivider />}