Merge pull request #749 from vector-im/erikj/mute_shortcuts

Add 'm' and 'space' shortcuts for mute/unmuting during a call
This commit is contained in:
Erik Johnston 2022-11-15 13:21:22 +00:00 committed by GitHub
commit 18139f78d2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 112 additions and 4 deletions

View file

@ -42,6 +42,7 @@
"Display name": "Display name",
"Download debug logs": "Download debug logs",
"Element Call Home": "Element Call Home",
"Single-key keyboard shortcuts": "Single-key keyboard shortcuts",
"Entering room…": "Entering room…",
"Exit full screen": "Exit full screen",
"Fetching group call timed out.": "Fetching group call timed out.",
@ -133,6 +134,7 @@
"Walkie-talkie call": "Walkie-talkie call",
"Walkie-talkie call name": "Walkie-talkie call name",
"WebRTC is not supported or is being blocked in this browser.": "WebRTC is not supported or is being blocked in this browser.",
"Whether to enable single-key keyboard shortcuts, e.g. 'm' to mute/unmute the mic.": "Whether to enable single-key keyboard shortcuts, e.g. 'm' to mute/unmute the mic.",
"Yes, join call": "Yes, join call",
"You can't talk at the same time": "You can't talk at the same time",
"Your recent calls": "Your recent calls"

View file

@ -14,7 +14,11 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import { DEFAULT_CONFIG, ConfigOptions, ResolvedConfigOptions } from "./ConfigOptions";
import {
DEFAULT_CONFIG,
ConfigOptions,
ResolvedConfigOptions,
} from "./ConfigOptions";
export class Config {
private static internalInstance: Config;

View file

@ -23,6 +23,7 @@ import { ReactComponent as MicIcon } from "../icons/Mic.svg";
import { useEventTarget } from "../useEvents";
import { Avatar } from "../Avatar";
import { usePrefersReducedMotion } from "../usePrefersReducedMotion";
import { getSetting } from "../settings/useSetting";
interface Props {
enabled: boolean;
@ -134,6 +135,12 @@ export const PTTButton: React.FC<Props> = ({
(e: KeyboardEvent) => {
if (e.code === "Space") {
if (!enabled) return;
// Check if keyboard shortcuts are enabled
const keyboardShortcuts = getSetting("keyboard-shortcuts", true);
if (!keyboardShortcuts) {
return;
}
e.preventDefault();
hold();
@ -148,6 +155,12 @@ export const PTTButton: React.FC<Props> = ({
useCallback(
(e: KeyboardEvent) => {
if (e.code === "Space") {
// Check if keyboard shortcuts are enabled
const keyboardShortcuts = getSetting("keyboard-shortcuts", true);
if (!keyboardShortcuts) {
return;
}
e.preventDefault();
unhold();

View file

@ -33,6 +33,8 @@ 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 interface UseGroupCallReturnType {
state: GroupCallState;
@ -298,11 +300,18 @@ export function useGroupCall(groupCall: GroupCall): UseGroupCallReturnType {
PosthogAnalytics.instance.eventMuteCamera.track(toggleToMute);
}, [groupCall]);
const setMicrophoneMuted = useCallback(
(setMuted) => {
groupCall.setMicrophoneMuted(setMuted);
PosthogAnalytics.instance.eventMuteMicrophone.track(setMuted);
},
[groupCall]
);
const toggleMicrophoneMuted = useCallback(() => {
const toggleToMute = !groupCall.isMicrophoneMuted();
groupCall.setMicrophoneMuted(toggleToMute);
PosthogAnalytics.instance.eventMuteMicrophone.track(toggleToMute);
}, [groupCall]);
setMicrophoneMuted(toggleToMute);
}, [groupCall, setMicrophoneMuted]);
const toggleScreensharing = useCallback(async () => {
if (!groupCall.isScreensharing()) {
@ -395,6 +404,68 @@ export function useGroupCall(groupCall: GroupCall): UseGroupCallReturnType {
}
}, [t]);
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,
calls,

View file

@ -28,6 +28,7 @@ import { ReactComponent as OverflowIcon } from "../icons/Overflow.svg";
import { SelectInput } from "../input/SelectInput";
import { useMediaHandler } from "./useMediaHandler";
import {
useKeyboardShortcuts,
useSpatialAudio,
useShowInspector,
useOptInAnalytics,
@ -59,6 +60,7 @@ export const SettingsModal = (props: Props) => {
const [spatialAudio, setSpatialAudio] = useSpatialAudio();
const [showInspector, setShowInspector] = useShowInspector();
const [optInAnalytics, setOptInAnalytics] = useOptInAnalytics();
const [keyboardShortcuts, setKeyboardShortcuts] = useKeyboardShortcuts();
const downloadDebugLog = useDownloadDebugLog();
@ -166,6 +168,20 @@ export const SettingsModal = (props: Props) => {
}
/>
</FieldRow>
<FieldRow>
<InputField
id="keyboardShortcuts"
label={t("Single-key keyboard shortcuts")}
type="checkbox"
checked={keyboardShortcuts}
description={t(
"Whether to enable single-key keyboard shortcuts, e.g. 'm' to mute/unmute the mic."
)}
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
setKeyboardShortcuts(event.target.checked)
}
/>
</FieldRow>
</TabItem>
<TabItem
title={

View file

@ -61,3 +61,5 @@ export const getSetting = <T>(name: string, defaultValue: T): T => {
export const useSpatialAudio = () => useSetting("spatial-audio", false);
export const useShowInspector = () => useSetting("show-inspector", false);
export const useOptInAnalytics = () => useSetting("opt-in-analytics", false);
export const useKeyboardShortcuts = () =>
useSetting("keyboard-shortcuts", true);