From f17e0a3ba0e265423c4977dfe02d3f1e5cc28959 Mon Sep 17 00:00:00 2001 From: lebaudantoine Date: Thu, 21 Aug 2025 23:38:44 +0200 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F(frontend)=20replace=20toggle?= =?UTF-8?q?=20device=20config=20with=20keyboard=20shortcut=20hook?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove ugly toggle device configuration and implement hook to determine appropriate keyboard shortcuts based on media device kind. Cleaner approach that encapsulates shortcut logic in reusable hook instead of scattered configuration objects. --- .../src/features/rooms/components/Join.tsx | 6 +-- .../rooms/components/join/ToggleDevice.tsx | 35 ++++++++--------- .../controls/Device/AudioDevicesControl.tsx | 13 +------ .../controls/Device/ToggleDevice.tsx | 21 +++++----- .../controls/Device/VideoDeviceControl.tsx | 11 +----- .../livekit/config/ToggleDeviceConfig.ts | 39 ------------------- .../rooms/livekit/hooks/useDeviceShortcut.ts | 21 ++++++++++ 7 files changed, 54 insertions(+), 92 deletions(-) delete mode 100644 src/frontend/src/features/rooms/livekit/config/ToggleDeviceConfig.ts create mode 100644 src/frontend/src/features/rooms/livekit/hooks/useDeviceShortcut.ts diff --git a/src/frontend/src/features/rooms/components/Join.tsx b/src/frontend/src/features/rooms/components/Join.tsx index da5ed28c..4ecfd19a 100644 --- a/src/frontend/src/features/rooms/components/Join.tsx +++ b/src/frontend/src/features/rooms/components/Join.tsx @@ -660,18 +660,16 @@ export const Join = ({ })} > saveAudioInputEnabled(enabled)} - onDeviceError={(error) => console.error(error)} /> saveVideoInputEnabled(enabled)} - onDeviceError={(error) => console.error(error)} />
= UseTrackToggleProps & { +type ToggleSource = Exclude< + Track.Source, + | Track.Source.ScreenShareAudio + | Track.Source.Unknown + | Track.Source.ScreenShare +> + +type ToggleDeviceProps = Pick< + UseTrackToggleProps, + 'onChange' | 'initialState' +> & { track?: LocalAudioTrack | LocalVideoTrack - source: ToggleSource + kind: MediaDeviceKind variant?: NonNullable['variant'] } export const ToggleDevice = ({ track, + kind, onChange, - ...props + initialState, }: ToggleDeviceProps) => { - const config = TOGGLE_DEVICE_CONFIG[props.source] - - if (!config) { - throw new Error('Invalid source') - } - - const [isTrackEnabled, setIsTrackEnabled] = useState( - props.initialState ?? false - ) + const [isTrackEnabled, setIsTrackEnabled] = useState(initialState ?? false) const toggle = useCallback(async () => { try { @@ -49,7 +48,7 @@ export const ToggleDevice = ({ { - const config: ToggleDeviceConfig = { - kind: 'audioinput', - shortcut: { - key: 'd', - ctrlKey: true, - }, - longPress: { - key: 'Space', - }, - } const { t } = useTranslation('rooms', { keyPrefix: 'join' }) const { @@ -67,7 +56,7 @@ export const AudioDevicesControl = ({ > void - config: ToggleDeviceConfig + kind: 'audioinput' | 'videoinput' variant?: NonNullable['variant'] errorVariant?: NonNullable['variant'] toggleButtonProps?: Partial } export const ToggleDevice = ({ - config, + kind, enabled, toggle, variant = 'primaryDark', @@ -37,8 +37,6 @@ export const ToggleDevice = ({ }: ToggleDeviceProps) => { const { t } = useTranslation('rooms', { keyPrefix: 'join' }) - const { kind, shortcut, longPress } = config - const [pushToTalk, setPushToTalk] = useState(false) const onKeyDown = () => { @@ -54,16 +52,21 @@ export const ToggleDevice = ({ const deviceIcons = useDeviceIcons(kind) const cannotUseDevice = useCannotUseDevice(kind) + const deviceShortcut = useDeviceShortcut(kind) - useRegisterKeyboardShortcut({ shortcut, handler: toggle }) - useLongPress({ keyCode: longPress?.key, onKeyDown, onKeyUp }) + useRegisterKeyboardShortcut({ shortcut: deviceShortcut, handler: toggle }) + useLongPress({ + keyCode: kind === 'audioinput' ? 'Space' : undefined, + onKeyDown, + onKeyUp, + }) const toggleLabel = useMemo(() => { const label = t(enabled ? 'disable' : 'enable', { keyPrefix: `join.${kind}`, }) - return shortcut ? appendShortcutLabel(label, shortcut) : label - }, [enabled, kind, shortcut, t]) + return deviceShortcut ? appendShortcutLabel(label, deviceShortcut) : label + }, [enabled, kind, deviceShortcut, t]) const Icon = enabled && !cannotUseDevice ? deviceIcons.toggleOn : deviceIcons.toggleOff diff --git a/src/frontend/src/features/rooms/livekit/components/controls/Device/VideoDeviceControl.tsx b/src/frontend/src/features/rooms/livekit/components/controls/Device/VideoDeviceControl.tsx index 12ee8772..a59f6752 100644 --- a/src/frontend/src/features/rooms/livekit/components/controls/Device/VideoDeviceControl.tsx +++ b/src/frontend/src/features/rooms/livekit/components/controls/Device/VideoDeviceControl.tsx @@ -9,7 +9,6 @@ import { css } from '@/styled-system/css' import { usePersistentUserChoices } from '../../../hooks/usePersistentUserChoices' import { useCannotUseDevice } from '../../../hooks/useCannotUseDevice' import { BackgroundProcessorFactory } from '../../blur' -import { ToggleDeviceConfig } from '../../../config/ToggleDeviceConfig' import Source = Track.Source import * as React from 'react' import { SelectDevice } from './SelectDevice' @@ -25,14 +24,6 @@ export const VideoDeviceControl = ({ hideMenu, ...props }: VideoDeviceControlProps) => { - const config: ToggleDeviceConfig = { - kind: 'videoinput', - shortcut: { - key: 'e', - ctrlKey: true, - }, - } - const { t } = useTranslation('rooms', { keyPrefix: 'join' }) const { userChoices, saveVideoInputDeviceId, saveVideoInputEnabled } = @@ -90,7 +81,7 @@ export const VideoDeviceControl = ({ > - -export type ToggleDeviceConfig = { - kind: MediaDeviceKind - shortcut?: Shortcut - longPress?: Shortcut -} - -type ToggleDeviceConfigMap = { - [key in ToggleSource]: ToggleDeviceConfig -} - -export const TOGGLE_DEVICE_CONFIG = { - [Track.Source.Microphone]: { - kind: 'audioinput', - shortcut: { - key: 'd', - ctrlKey: true, - }, - longPress: { - key: 'Space', - }, - }, - [Track.Source.Camera]: { - kind: 'videoinput', - shortcut: { - key: 'e', - ctrlKey: true, - }, - }, -} as const satisfies ToggleDeviceConfigMap diff --git a/src/frontend/src/features/rooms/livekit/hooks/useDeviceShortcut.ts b/src/frontend/src/features/rooms/livekit/hooks/useDeviceShortcut.ts new file mode 100644 index 00000000..8b05925f --- /dev/null +++ b/src/frontend/src/features/rooms/livekit/hooks/useDeviceShortcut.ts @@ -0,0 +1,21 @@ +import { useMemo } from 'react' +import { Shortcut } from '@/features/shortcuts/types' + +export const useDeviceShortcut = (kind: MediaDeviceKind) => { + return useMemo(() => { + switch (kind) { + case 'audioinput': + return { + key: 'e', + ctrlKey: true, + } + case 'videoinput': + return { + key: 'd', + ctrlKey: true, + } + default: + return undefined + } + }, [kind]) +}