Convert useGroupCall to TS
This commit is contained in:
299
src/room/useGroupCall.ts
Normal file
299
src/room/useGroupCall.ts
Normal file
@@ -0,0 +1,299 @@
|
||||
/*
|
||||
Copyright 2022 Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import {
|
||||
GroupCallEvent,
|
||||
GroupCallState,
|
||||
GroupCall,
|
||||
} from "matrix-js-sdk/src/webrtc/groupCall";
|
||||
import { MatrixCall } from "matrix-js-sdk/src/webrtc/call";
|
||||
import { CallFeed } from "matrix-js-sdk/src/webrtc/callFeed";
|
||||
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
||||
|
||||
import { usePageUnload } from "./usePageUnload";
|
||||
|
||||
interface State {
|
||||
state: GroupCallState;
|
||||
calls: MatrixCall[];
|
||||
localCallFeed: CallFeed;
|
||||
activeSpeaker: string;
|
||||
userMediaFeeds: CallFeed[];
|
||||
error: Error;
|
||||
microphoneMuted: boolean;
|
||||
localVideoMuted: boolean;
|
||||
screenshareFeeds: CallFeed[];
|
||||
localScreenshareFeed: CallFeed;
|
||||
localDesktopCapturerSourceId: string;
|
||||
isScreensharing: boolean;
|
||||
requestingScreenshare: boolean;
|
||||
participants: RoomMember[];
|
||||
hasLocalParticipant: boolean;
|
||||
}
|
||||
|
||||
export function useGroupCall(groupCall: GroupCall) {
|
||||
const [
|
||||
{
|
||||
state,
|
||||
calls,
|
||||
localCallFeed,
|
||||
activeSpeaker,
|
||||
userMediaFeeds,
|
||||
error,
|
||||
microphoneMuted,
|
||||
localVideoMuted,
|
||||
isScreensharing,
|
||||
screenshareFeeds,
|
||||
localScreenshareFeed,
|
||||
localDesktopCapturerSourceId,
|
||||
participants,
|
||||
hasLocalParticipant,
|
||||
requestingScreenshare,
|
||||
},
|
||||
setState,
|
||||
] = useState<State>({
|
||||
state: GroupCallState.LocalCallFeedUninitialized,
|
||||
calls: [],
|
||||
localCallFeed: null,
|
||||
activeSpeaker: null,
|
||||
userMediaFeeds: [],
|
||||
error: null,
|
||||
microphoneMuted: false,
|
||||
localVideoMuted: false,
|
||||
isScreensharing: false,
|
||||
screenshareFeeds: [],
|
||||
localScreenshareFeed: null,
|
||||
localDesktopCapturerSourceId: null,
|
||||
requestingScreenshare: false,
|
||||
participants: [],
|
||||
hasLocalParticipant: false,
|
||||
});
|
||||
|
||||
const updateState = (state: Partial<State>) =>
|
||||
setState((prevState) => ({ ...prevState, ...state }));
|
||||
|
||||
useEffect(() => {
|
||||
function onGroupCallStateChanged() {
|
||||
updateState({
|
||||
state: groupCall.state,
|
||||
calls: [...groupCall.calls],
|
||||
localCallFeed: groupCall.localCallFeed,
|
||||
activeSpeaker: groupCall.activeSpeaker,
|
||||
userMediaFeeds: [...groupCall.userMediaFeeds],
|
||||
microphoneMuted: groupCall.isMicrophoneMuted(),
|
||||
localVideoMuted: groupCall.isLocalVideoMuted(),
|
||||
isScreensharing: groupCall.isScreensharing(),
|
||||
localScreenshareFeed: groupCall.localScreenshareFeed,
|
||||
localDesktopCapturerSourceId: groupCall.localDesktopCapturerSourceId,
|
||||
screenshareFeeds: [...groupCall.screenshareFeeds],
|
||||
participants: [...groupCall.participants],
|
||||
});
|
||||
}
|
||||
|
||||
function onUserMediaFeedsChanged(userMediaFeeds: CallFeed[]): void {
|
||||
updateState({
|
||||
userMediaFeeds: [...userMediaFeeds],
|
||||
});
|
||||
}
|
||||
|
||||
function onScreenshareFeedsChanged(screenshareFeeds: CallFeed[]): void {
|
||||
updateState({
|
||||
screenshareFeeds: [...screenshareFeeds],
|
||||
});
|
||||
}
|
||||
|
||||
function onActiveSpeakerChanged(activeSpeaker: string): void {
|
||||
updateState({
|
||||
activeSpeaker: activeSpeaker,
|
||||
});
|
||||
}
|
||||
|
||||
function onLocalMuteStateChanged(
|
||||
microphoneMuted: boolean,
|
||||
localVideoMuted: boolean
|
||||
): void {
|
||||
updateState({
|
||||
microphoneMuted,
|
||||
localVideoMuted,
|
||||
});
|
||||
}
|
||||
|
||||
function onLocalScreenshareStateChanged(
|
||||
isScreensharing: boolean,
|
||||
localScreenshareFeed: CallFeed,
|
||||
localDesktopCapturerSourceId: string
|
||||
): void {
|
||||
updateState({
|
||||
isScreensharing,
|
||||
localScreenshareFeed,
|
||||
localDesktopCapturerSourceId,
|
||||
});
|
||||
}
|
||||
|
||||
function onCallsChanged(calls: MatrixCall[]): void {
|
||||
updateState({
|
||||
calls: [...calls],
|
||||
});
|
||||
}
|
||||
|
||||
function onParticipantsChanged(participants: RoomMember[]): void {
|
||||
updateState({
|
||||
participants: [...participants],
|
||||
hasLocalParticipant: groupCall.hasLocalParticipant(),
|
||||
});
|
||||
}
|
||||
|
||||
groupCall.on(GroupCallEvent.GroupCallStateChanged, onGroupCallStateChanged);
|
||||
groupCall.on(GroupCallEvent.UserMediaFeedsChanged, onUserMediaFeedsChanged);
|
||||
groupCall.on(
|
||||
GroupCallEvent.ScreenshareFeedsChanged,
|
||||
onScreenshareFeedsChanged
|
||||
);
|
||||
groupCall.on(GroupCallEvent.ActiveSpeakerChanged, onActiveSpeakerChanged);
|
||||
groupCall.on(GroupCallEvent.LocalMuteStateChanged, onLocalMuteStateChanged);
|
||||
groupCall.on(
|
||||
GroupCallEvent.LocalScreenshareStateChanged,
|
||||
onLocalScreenshareStateChanged
|
||||
);
|
||||
groupCall.on(GroupCallEvent.CallsChanged, onCallsChanged);
|
||||
groupCall.on(GroupCallEvent.ParticipantsChanged, onParticipantsChanged);
|
||||
|
||||
updateState({
|
||||
error: null,
|
||||
state: groupCall.state,
|
||||
calls: [...groupCall.calls],
|
||||
localCallFeed: groupCall.localCallFeed,
|
||||
activeSpeaker: groupCall.activeSpeaker,
|
||||
userMediaFeeds: [...groupCall.userMediaFeeds],
|
||||
microphoneMuted: groupCall.isMicrophoneMuted(),
|
||||
localVideoMuted: groupCall.isLocalVideoMuted(),
|
||||
isScreensharing: groupCall.isScreensharing(),
|
||||
localScreenshareFeed: groupCall.localScreenshareFeed,
|
||||
localDesktopCapturerSourceId: groupCall.localDesktopCapturerSourceId,
|
||||
screenshareFeeds: [...groupCall.screenshareFeeds],
|
||||
participants: [...groupCall.participants],
|
||||
hasLocalParticipant: groupCall.hasLocalParticipant(),
|
||||
});
|
||||
|
||||
return () => {
|
||||
groupCall.removeListener(
|
||||
GroupCallEvent.GroupCallStateChanged,
|
||||
onGroupCallStateChanged
|
||||
);
|
||||
groupCall.removeListener(
|
||||
GroupCallEvent.UserMediaFeedsChanged,
|
||||
onUserMediaFeedsChanged
|
||||
);
|
||||
groupCall.removeListener(
|
||||
GroupCallEvent.ScreenshareFeedsChanged,
|
||||
onScreenshareFeedsChanged
|
||||
);
|
||||
groupCall.removeListener(
|
||||
GroupCallEvent.ActiveSpeakerChanged,
|
||||
onActiveSpeakerChanged
|
||||
);
|
||||
groupCall.removeListener(
|
||||
GroupCallEvent.LocalMuteStateChanged,
|
||||
onLocalMuteStateChanged
|
||||
);
|
||||
groupCall.removeListener(
|
||||
GroupCallEvent.LocalScreenshareStateChanged,
|
||||
onLocalScreenshareStateChanged
|
||||
);
|
||||
groupCall.removeListener(GroupCallEvent.CallsChanged, onCallsChanged);
|
||||
groupCall.removeListener(
|
||||
GroupCallEvent.ParticipantsChanged,
|
||||
onParticipantsChanged
|
||||
);
|
||||
groupCall.leave();
|
||||
};
|
||||
}, [groupCall]);
|
||||
|
||||
usePageUnload(() => {
|
||||
groupCall.leave();
|
||||
});
|
||||
|
||||
const initLocalCallFeed = useCallback(
|
||||
() => groupCall.initLocalCallFeed(),
|
||||
[groupCall]
|
||||
);
|
||||
|
||||
const enter = useCallback(() => {
|
||||
if (
|
||||
groupCall.state !== GroupCallState.LocalCallFeedUninitialized &&
|
||||
groupCall.state !== GroupCallState.LocalCallFeedInitialized
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
groupCall.enter().catch((error) => {
|
||||
console.error(error);
|
||||
updateState({ error });
|
||||
});
|
||||
}, [groupCall]);
|
||||
|
||||
const leave = useCallback(() => groupCall.leave(), [groupCall]);
|
||||
|
||||
const toggleLocalVideoMuted = useCallback(() => {
|
||||
groupCall.setLocalVideoMuted(!groupCall.isLocalVideoMuted());
|
||||
}, [groupCall]);
|
||||
|
||||
const toggleMicrophoneMuted = useCallback(() => {
|
||||
groupCall.setMicrophoneMuted(!groupCall.isMicrophoneMuted());
|
||||
}, [groupCall]);
|
||||
|
||||
const toggleScreensharing = useCallback(() => {
|
||||
updateState({ requestingScreenshare: true });
|
||||
|
||||
groupCall.setScreensharingEnabled(!groupCall.isScreensharing()).then(() => {
|
||||
updateState({ requestingScreenshare: false });
|
||||
});
|
||||
}, [groupCall]);
|
||||
|
||||
useEffect(() => {
|
||||
if (window.RTCPeerConnection === undefined) {
|
||||
const error = new Error(
|
||||
"WebRTC is not supported or is being blocked in this browser."
|
||||
);
|
||||
console.error(error);
|
||||
updateState({ error });
|
||||
}
|
||||
}, []);
|
||||
|
||||
return {
|
||||
state,
|
||||
calls,
|
||||
localCallFeed,
|
||||
activeSpeaker,
|
||||
userMediaFeeds,
|
||||
microphoneMuted,
|
||||
localVideoMuted,
|
||||
error,
|
||||
initLocalCallFeed,
|
||||
enter,
|
||||
leave,
|
||||
toggleLocalVideoMuted,
|
||||
toggleMicrophoneMuted,
|
||||
toggleScreensharing,
|
||||
requestingScreenshare,
|
||||
isScreensharing,
|
||||
screenshareFeeds,
|
||||
localScreenshareFeed,
|
||||
localDesktopCapturerSourceId,
|
||||
participants,
|
||||
hasLocalParticipant,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user