fix: PTT blur/unmute, EC button hiding robustness, PTT status indicator

This commit is contained in:
root
2026-05-14 19:29:45 -04:00
parent 69091bc055
commit 94722c8a97
4 changed files with 63 additions and 9 deletions
+18 -1
View File
@@ -5,6 +5,8 @@ import { StatusDivider } from './components';
import { CallEmbed, useCallControlState } from '../../plugins/call';
import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback';
import { callEmbedAtom } from '../../state/callEmbed';
import { useSetting } from '../../state/hooks/settings';
import { settingsAtom } from '../../state/settings';
type MicrophoneButtonProps = {
enabled: boolean;
@@ -157,6 +159,9 @@ export function CallControl({
}) {
const { microphone, video, sound, screenshare } = useCallControlState(callEmbed.control);
const setCallEmbed = useSetAtom(callEmbedAtom);
const [pttMode] = useSetting(settingsAtom, 'pttMode');
const [pttKey] = useSetting(settingsAtom, 'pttKey');
const pttKeyLabel = pttMode ? (pttKey === 'Space' ? 'SPACE' : pttKey.replace('Key', '').replace('Digit', '')) : '';
const [hangupState, hangup] = useAsyncCallback(
useCallback(() => callEmbed.hangup(), [callEmbed])
@@ -175,10 +180,22 @@ export function CallControl({
return (
<Box shrink="No" alignItems="Center" gap="300">
<Box alignItems="Inherit" gap="200">
{pttMode && (
<Chip
variant="Critical"
fill="Soft"
radii="300"
size="300"
outlined
style={{ pointerEvents: 'none', fontWeight: 700, letterSpacing: '0.06em' }}
>
<Text size="T200">PTT {pttKeyLabel}</Text>
</Chip>
)}
<MicrophoneButton
enabled={microphone}
onToggle={() => callEmbed.control.toggleMicrophone()}
disabled={!callJoined}
disabled={!callJoined || pttMode}
/>
<SoundButton
enabled={sound}
+14 -3
View File
@@ -58,14 +58,18 @@ export function CallControls({ callEmbed }: CallControlsProps) {
const [pttKey] = useSetting(settingsAtom, 'pttKey');
const [pttActive, setPttActive] = useState(false);
// Mute mic immediately when PTT is enabled mid-call so the key handler can activate
// Handle PTT mode toggle mid-call
const pttModeRef = useRef(pttMode);
useEffect(() => {
if (pttMode && !pttModeRef.current && microphone) {
if (pttMode && !pttModeRef.current) {
// PTT just enabled — mute mic so key handler can activate
callEmbed.control.setMicrophone(false);
} else if (!pttMode && pttModeRef.current) {
// PTT just disabled — restore mic to on
callEmbed.control.setMicrophone(true);
}
pttModeRef.current = pttMode;
}, [pttMode, callEmbed, microphone]);
}, [pttMode, callEmbed]);
const handleOpenMenu: MouseEventHandler<HTMLButtonElement> = (evt) => {
setCords(evt.currentTarget.getBoundingClientRect());
@@ -101,11 +105,18 @@ export function CallControls({ callEmbed }: CallControlsProps) {
setPttActive(false);
}
};
// Release PTT if the tab loses focus — prevents mic getting stuck on after tab switching
const onBlur = () => {
callEmbed.control.setMicrophone(false);
setPttActive(false);
};
window.addEventListener('keydown', onKeyDown);
window.addEventListener('keyup', onKeyUp);
window.addEventListener('blur', onBlur);
return () => {
window.removeEventListener('keydown', onKeyDown);
window.removeEventListener('keyup', onKeyUp);
window.removeEventListener('blur', onBlur);
};
}, [pttMode, pttKey, callEmbed, microphone]);
+1
View File
@@ -21,6 +21,7 @@ export const CallMemberCard = style({
export const CallControlContainer = style({
padding: config.space.S400,
position: 'relative',
});
export const PrescreenMessage = style({