Files
cinny/src/app/plugins/call/hooks.ts
T

64 lines
2.1 KiB
TypeScript
Raw Normal View History

+4
2026-03-07 18:03:32 +11:00
import {
ClientWidgetApi,
IWidgetApiAcknowledgeResponseData,
IWidgetApiRequestData,
} from 'matrix-widget-api';
import { useCallback, useEffect, useState } from 'react';
import { CallControl, CallControlEvent } from './CallControl';
import { CallControlState } from './CallControlState';
export const useClientWidgetApiEvent = <T>(
api: ClientWidgetApi | undefined,
type: string,
callback: (event: CustomEvent<T>) => void,
+4
2026-03-07 18:03:32 +11:00
) => {
useEffect(() => {
api?.on(`action:${type}`, callback);
return () => {
api?.off(`action:${type}`, callback);
};
}, [api, type, callback]);
};
export const useSendClientWidgetApiAction = (api: ClientWidgetApi) => {
const sendWidgetAction = useCallback(
async <T extends IWidgetApiRequestData = IWidgetApiRequestData>(
action: string,
data: T,
+4
2026-03-07 18:03:32 +11:00
): Promise<IWidgetApiAcknowledgeResponseData> => api.transport.send(action, data),
[api],
+4
2026-03-07 18:03:32 +11:00
);
return sendWidgetAction;
};
const DEFAULT_CONTROL_STATE = new CallControlState(false, false, false);
export const useCallControlState = (control: CallControl | undefined): CallControlState => {
// 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,
}));
+4
2026-03-07 18:03:32 +11:00
useEffect(() => {
if (!control) {
setEntry({ control, state: DEFAULT_CONTROL_STATE });
return;
}
setEntry({ control, state: control.getState() });
const handleUpdate = () => setEntry({ control, state: control.getState() });
+4
2026-03-07 18:03:32 +11:00
control.on(CallControlEvent.StateUpdate, handleUpdate);
return () => {
control.off(CallControlEvent.StateUpdate, handleUpdate);
};
}, [control]);
if (entry.control !== control) return control?.getState() ?? DEFAULT_CONTROL_STATE;
return entry.state;
+4
2026-03-07 18:03:32 +11:00
};