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:
co-authored by
Claude Opus 5.5
parent
75d55e861b
commit
3449338b3e
@@ -85,6 +85,11 @@ export class CallEmbed {
|
||||
|
||||
private lotusCallStateListeners = new Set<() => void>();
|
||||
|
||||
// [Gitea #146] Local mic level (0–3 bars) from io.lotus.mic_level.
|
||||
private micLevel = 0;
|
||||
|
||||
private micLevelListeners = new Set<() => void>();
|
||||
|
||||
// [Gitea #17] Listeners notified when the fork sends io.lotus.request_state.
|
||||
private forkStateRequestListeners = new Set<() => void>();
|
||||
|
||||
@@ -417,6 +422,15 @@ export class CallEmbed {
|
||||
}
|
||||
}),
|
||||
);
|
||||
this.disposables.push(
|
||||
this.listenAction('io.lotus.mic_level', (evt) => {
|
||||
const bars = (evt.detail as { data?: { bars?: unknown } } | undefined)?.data?.bars;
|
||||
const level = typeof bars === 'number' ? Math.max(0, Math.min(3, Math.round(bars))) : 0;
|
||||
if (level === this.micLevel) return;
|
||||
this.micLevel = level;
|
||||
this.micLevelListeners.forEach((l) => l());
|
||||
}),
|
||||
);
|
||||
// [Gitea #43] Screenshare + layout state from the fork; also switches the
|
||||
// call bar's layout / settings / reactions buttons to widget actions.
|
||||
this.disposables.push(
|
||||
@@ -766,6 +780,19 @@ export class CallEmbed {
|
||||
};
|
||||
}
|
||||
|
||||
/** [Gitea #146] Latest local mic level, 0–3 bars (0 while muted). */
|
||||
public getMicLevel(): number {
|
||||
return this.micLevel;
|
||||
}
|
||||
|
||||
/** [Gitea #146] Subscribe to mic level changes. Returns an unsubscribe. */
|
||||
public onMicLevel(cb: () => void): () => void {
|
||||
this.micLevelListeners.add(cb);
|
||||
return () => {
|
||||
this.micLevelListeners.delete(cb);
|
||||
};
|
||||
}
|
||||
|
||||
public onLotusCallState(cb: () => void): () => void {
|
||||
this.lotusCallStateListeners.add(cb);
|
||||
return () => {
|
||||
|
||||
@@ -3,9 +3,10 @@ import {
|
||||
IWidgetApiAcknowledgeResponseData,
|
||||
IWidgetApiRequestData,
|
||||
} from 'matrix-widget-api';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { useCallback, useEffect, useState, useSyncExternalStore } from 'react';
|
||||
import { CallControl, CallControlEvent } from './CallControl';
|
||||
import { CallControlState } from './CallControlState';
|
||||
import type { CallEmbed } from './CallEmbed';
|
||||
|
||||
export const useClientWidgetApiEvent = <T>(
|
||||
api: ClientWidgetApi | undefined,
|
||||
@@ -61,3 +62,14 @@ export const useCallControlState = (control: CallControl | undefined): CallContr
|
||||
if (entry.control !== control) return control?.getState() ?? DEFAULT_CONTROL_STATE;
|
||||
return entry.state;
|
||||
};
|
||||
|
||||
const noSubscribe = () => () => undefined;
|
||||
|
||||
/** [Gitea #146] The local mic level (0–3 bars) reported by the call, or 0. */
|
||||
export const useCallMicLevel = (callEmbed: CallEmbed | undefined): number => {
|
||||
const subscribe = useCallback(
|
||||
(cb: () => void) => (callEmbed ? callEmbed.onMicLevel(cb) : noSubscribe()),
|
||||
[callEmbed],
|
||||
);
|
||||
return useSyncExternalStore(subscribe, () => callEmbed?.getMicLevel() ?? 0);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user