From 64607ae8d0a2df95d505243f07b485f1d98c2e33 Mon Sep 17 00:00:00 2001 From: lebaudantoine Date: Fri, 27 Sep 2024 16:12:02 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8(frontend)=20introduce=20push=20to=20t?= =?UTF-8?q?alk=20on=20microphone?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I am not a huge fan of changing the component's behavior based on a if, but that the only way I found to have something quickly. Actually, the push to talk feature will always only applies to the microphone. No other devices will be concerned. Reuse the active speaker indicator to quickly bootstrap the feature. Some details should be improved in terms of UI. The UX is quite decent. --- .../controls/SelectToggleDevice.tsx | 4 +++ .../components/controls/ToggleDevice.tsx | 28 +++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/frontend/src/features/rooms/livekit/components/controls/SelectToggleDevice.tsx b/src/frontend/src/features/rooms/livekit/components/controls/SelectToggleDevice.tsx index 09bf0cc6..c7bb0e6a 100644 --- a/src/frontend/src/features/rooms/livekit/components/controls/SelectToggleDevice.tsx +++ b/src/frontend/src/features/rooms/livekit/components/controls/SelectToggleDevice.tsx @@ -32,6 +32,7 @@ export type SelectToggleDeviceConfig = { iconOn: RemixiconComponentType iconOff: RemixiconComponentType shortcut?: Shortcut + longPress?: Shortcut } type SelectToggleDeviceConfigMap = { @@ -47,6 +48,9 @@ const selectToggleDeviceConfig: SelectToggleDeviceConfigMap = { key: 'd', ctrlKey: true, }, + longPress: { + key: 'Space', + }, }, [Track.Source.Camera]: { kind: 'videoinput', diff --git a/src/frontend/src/features/rooms/livekit/components/controls/ToggleDevice.tsx b/src/frontend/src/features/rooms/livekit/components/controls/ToggleDevice.tsx index c8fcc283..b3cde887 100644 --- a/src/frontend/src/features/rooms/livekit/components/controls/ToggleDevice.tsx +++ b/src/frontend/src/features/rooms/livekit/components/controls/ToggleDevice.tsx @@ -1,9 +1,12 @@ import { ToggleButton } from '@/primitives' import { useRegisterKeyboardShortcut } from '@/features/shortcuts/useRegisterKeyboardShortcut' -import { useMemo } from 'react' +import { useMemo, useState } from 'react' import { appendShortcutLabel } from '@/features/shortcuts/utils' import { useTranslation } from 'react-i18next' import { SelectToggleDeviceConfig } from './SelectToggleDevice' +import useLongPress from '@/features/shortcuts/useLongPress' +import { ActiveSpeaker } from '@/features/rooms/components/ActiveSpeaker' +import { useIsSpeaking, useLocalParticipant } from '@livekit/components-react' export type ToggleDeviceProps = { enabled: boolean @@ -18,9 +21,23 @@ export const ToggleDevice = ({ }: ToggleDeviceProps) => { const { t } = useTranslation('rooms', { keyPrefix: 'join' }) - const { kind, shortcut, iconOn, iconOff } = config + const { kind, shortcut, iconOn, iconOff, longPress } = config + + const [pushToTalk, setPushToTalk] = useState(false) + + const onKeyDown = () => { + if (pushToTalk || enabled) return + toggle() + setPushToTalk(true) + } + const onKeyUp = () => { + if (!pushToTalk) return + toggle() + setPushToTalk(false) + } useRegisterKeyboardShortcut({ shortcut, handler: toggle }) + useLongPress({ keyCode: longPress?.key, onKeyDown, onKeyUp }) const toggleLabel = useMemo(() => { const label = t(enabled ? 'disable' : 'enable', { @@ -31,6 +48,13 @@ export const ToggleDevice = ({ const Icon = enabled ? iconOn : iconOff + const { localParticipant } = useLocalParticipant() + const isSpeaking = useIsSpeaking(localParticipant) + + if (kind === 'audioinput' && pushToTalk) { + return + } + return (