From 9ba4ce429fbc86f51a0412a529effdfc103f7bbb Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 12 Jan 2023 17:31:19 +0000 Subject: [PATCH] Disable keyboard shortcuts when feedback modal is open --- src/room/GroupCallView.tsx | 2 + src/room/InCallView.tsx | 10 ++++ src/room/useGroupCall.ts | 66 +------------------------- src/useKeyboardShortcuts.ts | 92 +++++++++++++++++++++++++++++++++++++ 4 files changed, 106 insertions(+), 64 deletions(-) create mode 100644 src/useKeyboardShortcuts.ts diff --git a/src/room/GroupCallView.tsx b/src/room/GroupCallView.tsx index e10c4df..8867ed4 100644 --- a/src/room/GroupCallView.tsx +++ b/src/room/GroupCallView.tsx @@ -75,6 +75,7 @@ export function GroupCallView({ toggleLocalVideoMuted, toggleMicrophoneMuted, toggleScreensharing, + setMicrophoneMuted, requestingScreenshare, isScreensharing, screenshareFeeds, @@ -251,6 +252,7 @@ export function GroupCallView({ localVideoMuted={localVideoMuted} toggleLocalVideoMuted={toggleLocalVideoMuted} toggleMicrophoneMuted={toggleMicrophoneMuted} + setMicrophoneMuted={setMicrophoneMuted} userMediaFeeds={userMediaFeeds} activeSpeaker={activeSpeaker} onLeave={onLeave} diff --git a/src/room/InCallView.tsx b/src/room/InCallView.tsx index 232d001..2969c9a 100644 --- a/src/room/InCallView.tsx +++ b/src/room/InCallView.tsx @@ -63,6 +63,7 @@ import { usePrefersReducedMotion } from "../usePrefersReducedMotion"; import { ParticipantInfo } from "./useGroupCall"; import { TileDescriptor } from "../video-grid/TileDescriptor"; import { AudioSink } from "../video-grid/AudioSink"; +import { useKeyboardShortcuts } from "../useKeyboardShortcuts"; const canScreenshare = "getDisplayMedia" in (navigator.mediaDevices ?? {}); // There is currently a bug in Safari our our code with cloning and sending MediaStreams @@ -81,6 +82,7 @@ interface Props { toggleLocalVideoMuted: () => void; toggleMicrophoneMuted: () => void; toggleScreensharing: () => void; + setMicrophoneMuted: (muted: boolean) => void; userMediaFeeds: CallFeed[]; activeSpeaker: CallFeed | null; onLeave: () => void; @@ -101,6 +103,7 @@ export function InCallView({ localVideoMuted, toggleLocalVideoMuted, toggleMicrophoneMuted, + setMicrophoneMuted, userMediaFeeds, activeSpeaker, onLeave, @@ -141,6 +144,13 @@ export function InCallView({ const { hideScreensharing } = useUrlParams(); + useKeyboardShortcuts( + !feedbackModalState.isOpen, + toggleMicrophoneMuted, + toggleLocalVideoMuted, + setMicrophoneMuted + ); + useEffect(() => { widget?.api.transport.send( layout === "freedom" diff --git a/src/room/useGroupCall.ts b/src/room/useGroupCall.ts index 77ef38f..f2d7f27 100644 --- a/src/room/useGroupCall.ts +++ b/src/room/useGroupCall.ts @@ -32,8 +32,6 @@ import { usePageUnload } from "./usePageUnload"; import { PosthogAnalytics } from "../PosthogAnalytics"; import { TranslatedError, translatedError } from "../TranslatedError"; import { ElementWidgetActions, ScreenshareStartData, widget } from "../widget"; -import { getSetting } from "../settings/useSetting"; -import { useEventTarget } from "../useEvents"; export enum ConnectionState { EstablishingCall = "establishing call", // call hasn't been established yet @@ -60,6 +58,7 @@ export interface UseGroupCallReturnType { toggleLocalVideoMuted: () => void; toggleMicrophoneMuted: () => void; toggleScreensharing: () => void; + setMicrophoneMuted: (muted: boolean) => void; requestingScreenshare: boolean; isScreensharing: boolean; screenshareFeeds: CallFeed[]; @@ -472,68 +471,6 @@ export function useGroupCall(groupCall: GroupCall): UseGroupCallReturnType { } }, [t, updateState]); - const [spacebarHeld, setSpacebarHeld] = useState(false); - - useEventTarget( - window, - "keydown", - useCallback( - (event: KeyboardEvent) => { - // Check if keyboard shortcuts are enabled - const keyboardShortcuts = getSetting("keyboard-shortcuts", true); - if (!keyboardShortcuts) { - return; - } - - if (event.key === "m") { - toggleMicrophoneMuted(); - } else if (event.key == "v") { - toggleLocalVideoMuted(); - } else if (event.key === " ") { - setSpacebarHeld(true); - setMicrophoneMuted(false); - } - }, - [ - toggleLocalVideoMuted, - toggleMicrophoneMuted, - setMicrophoneMuted, - setSpacebarHeld, - ] - ) - ); - - useEventTarget( - window, - "keyup", - useCallback( - (event: KeyboardEvent) => { - // Check if keyboard shortcuts are enabled - const keyboardShortcuts = getSetting("keyboard-shortcuts", true); - if (!keyboardShortcuts) { - return; - } - - if (event.key === " ") { - setSpacebarHeld(false); - setMicrophoneMuted(true); - } - }, - [setMicrophoneMuted, setSpacebarHeld] - ) - ); - - useEventTarget( - window, - "blur", - useCallback(() => { - if (spacebarHeld) { - setSpacebarHeld(false); - setMicrophoneMuted(true); - } - }, [setMicrophoneMuted, setSpacebarHeld, spacebarHeld]) - ); - return { state, localCallFeed, @@ -548,6 +485,7 @@ export function useGroupCall(groupCall: GroupCall): UseGroupCallReturnType { toggleLocalVideoMuted, toggleMicrophoneMuted, toggleScreensharing, + setMicrophoneMuted, requestingScreenshare, isScreensharing, screenshareFeeds, diff --git a/src/useKeyboardShortcuts.ts b/src/useKeyboardShortcuts.ts new file mode 100644 index 0000000..b9d69ec --- /dev/null +++ b/src/useKeyboardShortcuts.ts @@ -0,0 +1,92 @@ +/* +Copyright 2022-2023 New Vector Ltd + +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, useState } from "react"; + +import { getSetting } from "./settings/useSetting"; +import { useEventTarget } from "./useEvents"; + +export function useKeyboardShortcuts( + enabled: boolean, + toggleMicrophoneMuted: () => void, + toggleLocalVideoMuted: () => void, + setMicrophoneMuted: (muted: boolean) => void +) { + const [spacebarHeld, setSpacebarHeld] = useState(false); + + useEventTarget( + window, + "keydown", + useCallback( + (event: KeyboardEvent) => { + if (!enabled) return; + // Check if keyboard shortcuts are enabled + const keyboardShortcuts = getSetting("keyboard-shortcuts", true); + if (!keyboardShortcuts) { + return; + } + + if (event.key === "m") { + toggleMicrophoneMuted(); + } else if (event.key == "v") { + toggleLocalVideoMuted(); + } else if (event.key === " ") { + setSpacebarHeld(true); + setMicrophoneMuted(false); + } + }, + [ + enabled, + toggleLocalVideoMuted, + toggleMicrophoneMuted, + setMicrophoneMuted, + setSpacebarHeld, + ] + ) + ); + + useEventTarget( + window, + "keyup", + useCallback( + (event: KeyboardEvent) => { + if (!enabled) return; + // Check if keyboard shortcuts are enabled + const keyboardShortcuts = getSetting("keyboard-shortcuts", true); + if (!keyboardShortcuts) { + return; + } + + if (event.key === " ") { + setSpacebarHeld(false); + setMicrophoneMuted(true); + } + }, + [enabled, setMicrophoneMuted, setSpacebarHeld] + ) + ); + + useEventTarget( + window, + "blur", + useCallback(() => { + if (spacebarHeld) { + setSpacebarHeld(false); + setMicrophoneMuted(true); + } + }, [setMicrophoneMuted, setSpacebarHeld, spacebarHeld]) + ); +}