fix(calls): no stale "muted + deafened" render when a call starts
useCallControlState kept the previous control's state (the all-off default before a call) for one render after the control changed, until its effect caught up. The thumbbar, SMTC and tray hooks pushed that render to the OS, so every join flashed "muted + deafened" first (recorded: idle → active+muted+deafened → active). The state now remembers which control it belongs to and reads the new control directly when they differ (now: idle → active). 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
6edfe70020
commit
b77720c3da
@@ -35,20 +35,29 @@ export const useSendClientWidgetApiAction = (api: ClientWidgetApi) => {
|
||||
const DEFAULT_CONTROL_STATE = new CallControlState(false, false, false);
|
||||
|
||||
export const useCallControlState = (control: CallControl | undefined): CallControlState => {
|
||||
const [state, setState] = useState(control?.getState() ?? DEFAULT_CONTROL_STATE);
|
||||
// Remember which control the stored state came from. When a call starts the
|
||||
// control changes, and the effect below only catches up after a render; until
|
||||
// then the old (default: all off) state would be returned for the NEW call —
|
||||
// one render of "muted + deafened" that the thumbbar, SMTC and tray (#4)
|
||||
// pushed to the OS as a flicker. Read the new control directly instead.
|
||||
const [entry, setEntry] = useState(() => ({
|
||||
control,
|
||||
state: control?.getState() ?? DEFAULT_CONTROL_STATE,
|
||||
}));
|
||||
|
||||
useEffect(() => {
|
||||
if (!control) {
|
||||
setState(DEFAULT_CONTROL_STATE);
|
||||
setEntry({ control, state: DEFAULT_CONTROL_STATE });
|
||||
return;
|
||||
}
|
||||
setState(control.getState());
|
||||
const handleUpdate = () => setState(control.getState());
|
||||
setEntry({ control, state: control.getState() });
|
||||
const handleUpdate = () => setEntry({ control, state: control.getState() });
|
||||
control.on(CallControlEvent.StateUpdate, handleUpdate);
|
||||
return () => {
|
||||
control.off(CallControlEvent.StateUpdate, handleUpdate);
|
||||
};
|
||||
}, [control]);
|
||||
|
||||
return state;
|
||||
if (entry.control !== control) return control?.getState() ?? DEFAULT_CONTROL_STATE;
|
||||
return entry.state;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user