2022-05-04 17:09:48 +01:00
|
|
|
/*
|
|
|
|
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.
|
|
|
|
*/
|
|
|
|
|
2022-06-09 21:56:58 +01:00
|
|
|
import { useCallback, useEffect, useReducer, useState } from "react";
|
2022-04-07 14:22:36 -07:00
|
|
|
import {
|
|
|
|
GroupCallEvent,
|
|
|
|
GroupCallState,
|
2022-05-30 15:30:57 +01:00
|
|
|
GroupCall,
|
2022-06-09 21:56:58 +01:00
|
|
|
GroupCallErrorCode,
|
|
|
|
GroupCallUnknownDeviceError,
|
|
|
|
GroupCallError,
|
2022-04-07 14:22:36 -07:00
|
|
|
} from "matrix-js-sdk/src/webrtc/groupCall";
|
2022-05-30 15:30:57 +01:00
|
|
|
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";
|
2022-10-10 09:19:10 -04:00
|
|
|
import { useTranslation } from "react-i18next";
|
2022-10-21 20:19:52 +01:00
|
|
|
import { IWidgetApiRequest } from "matrix-widget-api";
|
2022-05-30 15:30:57 +01:00
|
|
|
|
2022-04-07 14:22:36 -07:00
|
|
|
import { usePageUnload } from "./usePageUnload";
|
2022-11-04 13:07:14 +01:00
|
|
|
import { PosthogAnalytics } from "../PosthogAnalytics";
|
2022-10-10 09:19:10 -04:00
|
|
|
import { TranslatedError, translatedError } from "../TranslatedError";
|
2022-10-21 20:19:52 +01:00
|
|
|
import { ElementWidgetActions, ScreenshareStartData, widget } from "../widget";
|
2022-11-14 10:21:24 +00:00
|
|
|
import { getSetting } from "../settings/useSetting";
|
2022-11-14 16:05:49 +00:00
|
|
|
import { useEventTarget } from "../useEvents";
|
2022-04-07 14:22:36 -07:00
|
|
|
|
2022-08-02 00:46:16 +02:00
|
|
|
export interface UseGroupCallReturnType {
|
2022-05-30 15:53:44 +01:00
|
|
|
state: GroupCallState;
|
|
|
|
calls: MatrixCall[];
|
|
|
|
localCallFeed: CallFeed;
|
|
|
|
activeSpeaker: string;
|
|
|
|
userMediaFeeds: CallFeed[];
|
|
|
|
microphoneMuted: boolean;
|
|
|
|
localVideoMuted: boolean;
|
2022-10-10 09:19:10 -04:00
|
|
|
error: TranslatedError | null;
|
2022-05-30 15:53:44 +01:00
|
|
|
initLocalCallFeed: () => void;
|
|
|
|
enter: () => void;
|
|
|
|
leave: () => void;
|
|
|
|
toggleLocalVideoMuted: () => void;
|
|
|
|
toggleMicrophoneMuted: () => void;
|
|
|
|
toggleScreensharing: () => void;
|
|
|
|
requestingScreenshare: boolean;
|
|
|
|
isScreensharing: boolean;
|
|
|
|
screenshareFeeds: CallFeed[];
|
2022-11-01 18:10:11 +00:00
|
|
|
localDesktopCapturerSourceId: string; // XXX: This looks unused?
|
2022-05-30 15:53:44 +01:00
|
|
|
participants: RoomMember[];
|
|
|
|
hasLocalParticipant: boolean;
|
2022-06-09 21:56:58 +01:00
|
|
|
unencryptedEventsFromUsers: Set<string>;
|
2022-05-30 15:53:44 +01:00
|
|
|
}
|
|
|
|
|
2022-05-30 15:30:57 +01:00
|
|
|
interface State {
|
|
|
|
state: GroupCallState;
|
|
|
|
calls: MatrixCall[];
|
|
|
|
localCallFeed: CallFeed;
|
|
|
|
activeSpeaker: string;
|
|
|
|
userMediaFeeds: CallFeed[];
|
2022-10-10 09:19:10 -04:00
|
|
|
error: TranslatedError | null;
|
2022-05-30 15:30:57 +01:00
|
|
|
microphoneMuted: boolean;
|
|
|
|
localVideoMuted: boolean;
|
|
|
|
screenshareFeeds: CallFeed[];
|
|
|
|
localDesktopCapturerSourceId: string;
|
|
|
|
isScreensharing: boolean;
|
|
|
|
requestingScreenshare: boolean;
|
|
|
|
participants: RoomMember[];
|
|
|
|
hasLocalParticipant: boolean;
|
|
|
|
}
|
|
|
|
|
2022-08-02 00:46:16 +02:00
|
|
|
export function useGroupCall(groupCall: GroupCall): UseGroupCallReturnType {
|
2022-04-07 14:22:36 -07:00
|
|
|
const [
|
|
|
|
{
|
|
|
|
state,
|
|
|
|
calls,
|
|
|
|
localCallFeed,
|
|
|
|
activeSpeaker,
|
|
|
|
userMediaFeeds,
|
|
|
|
error,
|
|
|
|
microphoneMuted,
|
|
|
|
localVideoMuted,
|
|
|
|
isScreensharing,
|
|
|
|
screenshareFeeds,
|
|
|
|
localDesktopCapturerSourceId,
|
|
|
|
participants,
|
|
|
|
hasLocalParticipant,
|
|
|
|
requestingScreenshare,
|
|
|
|
},
|
|
|
|
setState,
|
2022-05-30 15:30:57 +01:00
|
|
|
] = useState<State>({
|
2022-04-07 14:22:36 -07:00
|
|
|
state: GroupCallState.LocalCallFeedUninitialized,
|
|
|
|
calls: [],
|
2022-05-30 15:30:57 +01:00
|
|
|
localCallFeed: null,
|
|
|
|
activeSpeaker: null,
|
2022-04-07 14:22:36 -07:00
|
|
|
userMediaFeeds: [],
|
2022-05-30 15:30:57 +01:00
|
|
|
error: null,
|
2022-04-07 14:22:36 -07:00
|
|
|
microphoneMuted: false,
|
|
|
|
localVideoMuted: false,
|
|
|
|
isScreensharing: false,
|
2022-05-30 15:30:57 +01:00
|
|
|
screenshareFeeds: [],
|
|
|
|
localDesktopCapturerSourceId: null,
|
2022-04-07 14:22:36 -07:00
|
|
|
requestingScreenshare: false,
|
|
|
|
participants: [],
|
|
|
|
hasLocalParticipant: false,
|
|
|
|
});
|
|
|
|
|
2022-06-09 21:56:58 +01:00
|
|
|
const [unencryptedEventsFromUsers, addUnencryptedEventUser] = useReducer(
|
|
|
|
(state: Set<string>, newVal: string) => {
|
|
|
|
return new Set(state).add(newVal);
|
|
|
|
},
|
|
|
|
new Set<string>()
|
|
|
|
);
|
|
|
|
|
2022-05-30 15:30:57 +01:00
|
|
|
const updateState = (state: Partial<State>) =>
|
2022-04-07 14:22:36 -07:00
|
|
|
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(),
|
|
|
|
localDesktopCapturerSourceId: groupCall.localDesktopCapturerSourceId,
|
|
|
|
screenshareFeeds: [...groupCall.screenshareFeeds],
|
|
|
|
participants: [...groupCall.participants],
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-05-30 15:30:57 +01:00
|
|
|
function onUserMediaFeedsChanged(userMediaFeeds: CallFeed[]): void {
|
2022-04-07 14:22:36 -07:00
|
|
|
updateState({
|
|
|
|
userMediaFeeds: [...userMediaFeeds],
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-05-30 15:30:57 +01:00
|
|
|
function onScreenshareFeedsChanged(screenshareFeeds: CallFeed[]): void {
|
2022-04-07 14:22:36 -07:00
|
|
|
updateState({
|
|
|
|
screenshareFeeds: [...screenshareFeeds],
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-05-30 15:30:57 +01:00
|
|
|
function onActiveSpeakerChanged(activeSpeaker: string): void {
|
2022-04-07 14:22:36 -07:00
|
|
|
updateState({
|
|
|
|
activeSpeaker: activeSpeaker,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-05-30 15:30:57 +01:00
|
|
|
function onLocalMuteStateChanged(
|
|
|
|
microphoneMuted: boolean,
|
|
|
|
localVideoMuted: boolean
|
|
|
|
): void {
|
2022-04-07 14:22:36 -07:00
|
|
|
updateState({
|
|
|
|
microphoneMuted,
|
|
|
|
localVideoMuted,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function onLocalScreenshareStateChanged(
|
2022-05-30 15:30:57 +01:00
|
|
|
isScreensharing: boolean,
|
2022-10-21 17:24:56 +01:00
|
|
|
_localScreenshareFeed: CallFeed,
|
2022-05-30 15:30:57 +01:00
|
|
|
localDesktopCapturerSourceId: string
|
|
|
|
): void {
|
2022-04-07 14:22:36 -07:00
|
|
|
updateState({
|
|
|
|
isScreensharing,
|
|
|
|
localDesktopCapturerSourceId,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-05-30 15:30:57 +01:00
|
|
|
function onCallsChanged(calls: MatrixCall[]): void {
|
2022-04-07 14:22:36 -07:00
|
|
|
updateState({
|
|
|
|
calls: [...calls],
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-05-30 15:30:57 +01:00
|
|
|
function onParticipantsChanged(participants: RoomMember[]): void {
|
2022-04-07 14:22:36 -07:00
|
|
|
updateState({
|
|
|
|
participants: [...participants],
|
|
|
|
hasLocalParticipant: groupCall.hasLocalParticipant(),
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-06-09 21:56:58 +01:00
|
|
|
function onError(e: GroupCallError): void {
|
|
|
|
if (e.code === GroupCallErrorCode.UnknownDevice) {
|
|
|
|
const unknownDeviceError = e as GroupCallUnknownDeviceError;
|
|
|
|
addUnencryptedEventUser(unknownDeviceError.userId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-07 14:22:36 -07:00
|
|
|
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);
|
2022-06-09 21:56:58 +01:00
|
|
|
groupCall.on(GroupCallEvent.Error, onError);
|
2022-04-07 14:22:36 -07:00
|
|
|
|
|
|
|
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(),
|
|
|
|
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
|
|
|
|
);
|
2022-06-09 21:56:58 +01:00
|
|
|
groupCall.removeListener(GroupCallEvent.Error, onError);
|
2022-04-07 14:22:36 -07:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2022-11-04 13:07:14 +01:00
|
|
|
PosthogAnalytics.instance.eventCallEnded.cacheStartCall(new Date());
|
|
|
|
PosthogAnalytics.instance.eventCallStarted.track(groupCall.room.name);
|
|
|
|
|
2022-04-07 14:22:36 -07:00
|
|
|
groupCall.enter().catch((error) => {
|
|
|
|
console.error(error);
|
|
|
|
updateState({ error });
|
|
|
|
});
|
|
|
|
}, [groupCall]);
|
|
|
|
|
|
|
|
const leave = useCallback(() => groupCall.leave(), [groupCall]);
|
|
|
|
|
|
|
|
const toggleLocalVideoMuted = useCallback(() => {
|
2022-11-04 13:07:14 +01:00
|
|
|
const toggleToMute = !groupCall.isLocalVideoMuted();
|
|
|
|
groupCall.setLocalVideoMuted(toggleToMute);
|
|
|
|
PosthogAnalytics.instance.eventMuteCamera.track(toggleToMute);
|
2022-04-07 14:22:36 -07:00
|
|
|
}, [groupCall]);
|
|
|
|
|
2022-11-11 16:00:32 +00:00
|
|
|
const setMicrophoneMuted = useCallback(
|
|
|
|
(setMuted) => {
|
|
|
|
groupCall.setMicrophoneMuted(setMuted);
|
|
|
|
PosthogAnalytics.instance.eventMuteMicrophone.track(setMuted);
|
|
|
|
},
|
|
|
|
[groupCall]
|
|
|
|
);
|
2022-11-11 15:53:58 +00:00
|
|
|
|
2022-04-07 14:22:36 -07:00
|
|
|
const toggleMicrophoneMuted = useCallback(() => {
|
2022-11-04 13:07:14 +01:00
|
|
|
const toggleToMute = !groupCall.isMicrophoneMuted();
|
2022-11-11 15:53:58 +00:00
|
|
|
setMicrophoneMuted(toggleToMute);
|
2022-11-11 16:02:24 +00:00
|
|
|
}, [groupCall, setMicrophoneMuted]);
|
2022-04-07 14:22:36 -07:00
|
|
|
|
2022-10-21 20:19:52 +01:00
|
|
|
const toggleScreensharing = useCallback(async () => {
|
|
|
|
if (!groupCall.isScreensharing()) {
|
|
|
|
// toggling on
|
|
|
|
updateState({ requestingScreenshare: true });
|
2022-04-07 14:22:36 -07:00
|
|
|
|
2022-10-21 20:19:52 +01:00
|
|
|
try {
|
|
|
|
await groupCall.setScreensharingEnabled(true, {
|
|
|
|
audio: true,
|
|
|
|
throwOnFail: true,
|
|
|
|
});
|
2022-07-16 17:54:49 +02:00
|
|
|
updateState({ requestingScreenshare: false });
|
2022-10-21 20:19:52 +01:00
|
|
|
} catch (e) {
|
|
|
|
// this will fail in Electron because getDisplayMedia just throws a permission
|
|
|
|
// error, so if we have a widget API, try requesting via that.
|
|
|
|
if (widget) {
|
|
|
|
const reply = await widget.api.transport.send(
|
|
|
|
ElementWidgetActions.ScreenshareRequest,
|
|
|
|
{}
|
|
|
|
);
|
|
|
|
if (!reply.pending) {
|
|
|
|
updateState({ requestingScreenshare: false });
|
2022-10-20 19:07:27 +02:00
|
|
|
}
|
2022-10-21 20:19:52 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// toggling off
|
|
|
|
groupCall.setScreensharingEnabled(false);
|
2022-10-20 19:07:27 +02:00
|
|
|
}
|
2022-04-07 14:22:36 -07:00
|
|
|
}, [groupCall]);
|
|
|
|
|
2022-10-21 20:19:52 +01:00
|
|
|
const onScreenshareStart = useCallback(
|
|
|
|
async (ev: CustomEvent<IWidgetApiRequest>) => {
|
|
|
|
updateState({ requestingScreenshare: false });
|
2022-10-21 20:28:33 +01:00
|
|
|
|
|
|
|
const data = ev.detail.data as unknown as ScreenshareStartData;
|
|
|
|
|
2022-10-21 20:19:52 +01:00
|
|
|
await groupCall.setScreensharingEnabled(true, {
|
2022-10-21 20:28:33 +01:00
|
|
|
desktopCapturerSourceId: data.desktopCapturerSourceId as string,
|
|
|
|
audio: !data.desktopCapturerSourceId,
|
2022-10-21 20:19:52 +01:00
|
|
|
});
|
|
|
|
await widget.api.transport.reply(ev.detail, {});
|
|
|
|
},
|
|
|
|
[groupCall]
|
|
|
|
);
|
|
|
|
|
|
|
|
const onScreenshareStop = useCallback(
|
|
|
|
async (ev: CustomEvent<IWidgetApiRequest>) => {
|
|
|
|
updateState({ requestingScreenshare: false });
|
|
|
|
await groupCall.setScreensharingEnabled(false);
|
|
|
|
await widget.api.transport.reply(ev.detail, {});
|
|
|
|
},
|
|
|
|
[groupCall]
|
|
|
|
);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
if (widget) {
|
|
|
|
widget.lazyActions.on(
|
|
|
|
ElementWidgetActions.ScreenshareStart,
|
|
|
|
onScreenshareStart
|
|
|
|
);
|
|
|
|
widget.lazyActions.on(
|
|
|
|
ElementWidgetActions.ScreenshareStop,
|
|
|
|
onScreenshareStop
|
|
|
|
);
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
widget.lazyActions.off(
|
|
|
|
ElementWidgetActions.ScreenshareStart,
|
|
|
|
onScreenshareStart
|
|
|
|
);
|
|
|
|
widget.lazyActions.off(
|
|
|
|
ElementWidgetActions.ScreenshareStop,
|
|
|
|
onScreenshareStop
|
|
|
|
);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}, [onScreenshareStart, onScreenshareStop]);
|
|
|
|
|
2022-10-10 09:19:10 -04:00
|
|
|
const { t } = useTranslation();
|
|
|
|
|
2022-04-07 14:22:36 -07:00
|
|
|
useEffect(() => {
|
|
|
|
if (window.RTCPeerConnection === undefined) {
|
2022-10-10 09:19:10 -04:00
|
|
|
const error = translatedError(
|
|
|
|
"WebRTC is not supported or is being blocked in this browser.",
|
|
|
|
t
|
2022-04-07 14:22:36 -07:00
|
|
|
);
|
|
|
|
console.error(error);
|
|
|
|
updateState({ error });
|
|
|
|
}
|
2022-10-10 09:19:10 -04:00
|
|
|
}, [t]);
|
2022-04-07 14:22:36 -07:00
|
|
|
|
2022-11-14 20:55:24 +00:00
|
|
|
const [spacebarHeld, setSpacebarHeld] = useState(false);
|
|
|
|
|
2022-11-14 16:05:49 +00:00
|
|
|
useEventTarget(
|
|
|
|
window,
|
|
|
|
"keydown",
|
|
|
|
useCallback(
|
|
|
|
(event: KeyboardEvent) => {
|
|
|
|
// Check if keyboard shortcuts are enabled
|
|
|
|
const keyboardShortcuts = getSetting("keyboard-shortcuts", true);
|
|
|
|
if (!keyboardShortcuts) {
|
|
|
|
return;
|
|
|
|
}
|
2022-11-14 10:21:24 +00:00
|
|
|
|
2022-11-14 16:05:49 +00:00
|
|
|
if (event.key === "m") {
|
|
|
|
toggleMicrophoneMuted();
|
2022-11-14 16:14:16 +00:00
|
|
|
} else if (event.key == "v") {
|
|
|
|
toggleLocalVideoMuted();
|
|
|
|
} else if (event.key === " ") {
|
2022-11-14 20:55:24 +00:00
|
|
|
setSpacebarHeld(true);
|
2022-11-14 16:05:49 +00:00
|
|
|
setMicrophoneMuted(false);
|
|
|
|
}
|
|
|
|
},
|
2022-11-14 20:55:24 +00:00
|
|
|
[
|
|
|
|
toggleLocalVideoMuted,
|
|
|
|
toggleMicrophoneMuted,
|
|
|
|
setMicrophoneMuted,
|
|
|
|
setSpacebarHeld,
|
|
|
|
]
|
2022-11-14 16:05:49 +00:00
|
|
|
)
|
|
|
|
);
|
2022-11-11 15:53:58 +00:00
|
|
|
|
2022-11-14 16:05:49 +00:00
|
|
|
useEventTarget(
|
|
|
|
window,
|
|
|
|
"keyup",
|
|
|
|
useCallback(
|
|
|
|
(event: KeyboardEvent) => {
|
|
|
|
// Check if keyboard shortcuts are enabled
|
|
|
|
const keyboardShortcuts = getSetting("keyboard-shortcuts", true);
|
|
|
|
if (!keyboardShortcuts) {
|
|
|
|
return;
|
|
|
|
}
|
2022-11-11 15:53:58 +00:00
|
|
|
|
2022-11-14 16:05:49 +00:00
|
|
|
if (event.key === " ") {
|
2022-11-14 20:55:24 +00:00
|
|
|
setSpacebarHeld(false);
|
2022-11-14 16:05:49 +00:00
|
|
|
setMicrophoneMuted(true);
|
|
|
|
}
|
|
|
|
},
|
2022-11-14 20:55:24 +00:00
|
|
|
[setMicrophoneMuted, setSpacebarHeld]
|
2022-11-14 16:05:49 +00:00
|
|
|
)
|
|
|
|
);
|
2022-11-11 15:53:58 +00:00
|
|
|
|
2022-11-14 20:55:24 +00:00
|
|
|
useEventTarget(
|
|
|
|
window,
|
|
|
|
"blur",
|
|
|
|
useCallback(() => {
|
|
|
|
if (spacebarHeld) {
|
|
|
|
setSpacebarHeld(false);
|
|
|
|
setMicrophoneMuted(true);
|
|
|
|
}
|
|
|
|
}, [setMicrophoneMuted, setSpacebarHeld, spacebarHeld])
|
|
|
|
);
|
|
|
|
|
2022-04-07 14:22:36 -07:00
|
|
|
return {
|
|
|
|
state,
|
|
|
|
calls,
|
|
|
|
localCallFeed,
|
|
|
|
activeSpeaker,
|
|
|
|
userMediaFeeds,
|
|
|
|
microphoneMuted,
|
|
|
|
localVideoMuted,
|
|
|
|
error,
|
|
|
|
initLocalCallFeed,
|
|
|
|
enter,
|
|
|
|
leave,
|
|
|
|
toggleLocalVideoMuted,
|
|
|
|
toggleMicrophoneMuted,
|
|
|
|
toggleScreensharing,
|
|
|
|
requestingScreenshare,
|
|
|
|
isScreensharing,
|
|
|
|
screenshareFeeds,
|
|
|
|
localDesktopCapturerSourceId,
|
|
|
|
participants,
|
|
|
|
hasLocalParticipant,
|
2022-06-09 21:56:58 +01:00
|
|
|
unencryptedEventsFromUsers,
|
2022-04-07 14:22:36 -07:00
|
|
|
};
|
|
|
|
}
|