Files
cinny/src/app/hooks/useSpaceLiveCall.ts
T

47 lines
1.9 KiB
TypeScript
Raw Normal View History

import { useEffect, useMemo, useState } from 'react';
import { MatrixEvent, RoomStateEvent } from 'matrix-js-sdk';
import { MatrixRTCSessionManagerEvents } from 'matrix-js-sdk/lib/matrixrtc/MatrixRTCSessionManager';
import { useMatrixClient } from './useMatrixClient';
import { StateEvent } from '../../types/matrix/room';
/**
* [Gitea #148] Whether any of the given rooms has a live MatrixRTC call.
* Derived from the same session memberships the sidebar voice rows use;
* recomputed only when a session starts/ends or a call-member state event
* lands in one of the rooms — no per-render scans.
*/
export function useAnyRoomLiveCall(roomIds: string[]): boolean {
const mx = useMatrixClient();
const idSet = useMemo(() => new Set(roomIds), [roomIds]);
const compute = () =>
roomIds.some((id) => {
const room = mx.getRoom(id);
return !!room && mx.matrixRTC.getRoomSession(room).memberships.length > 0;
});
const [live, setLive] = useState(compute);
useEffect(() => {
setLive(compute());
const onSession = (roomId: string) => {
if (idSet.has(roomId)) setLive(compute());
};
const onState = (event: MatrixEvent) => {
if (event.getType() !== StateEvent.GroupCallMemberPrefix) return;
const roomId = event.getRoomId();
if (roomId && idSet.has(roomId)) setLive(compute());
};
mx.matrixRTC.on(MatrixRTCSessionManagerEvents.SessionStarted, onSession);
mx.matrixRTC.on(MatrixRTCSessionManagerEvents.SessionEnded, onSession);
mx.on(RoomStateEvent.Events, onState);
return () => {
mx.matrixRTC.off(MatrixRTCSessionManagerEvents.SessionStarted, onSession);
mx.matrixRTC.off(MatrixRTCSessionManagerEvents.SessionEnded, onSession);
mx.off(RoomStateEvent.Events, onState);
};
// compute closes over roomIds; idSet changes exactly when roomIds does
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [mx, idSet]);
return live;
}