diff --git a/src/frontend/src/features/rooms/components/join/SelectDevice.tsx b/src/frontend/src/features/rooms/components/join/SelectDevice.tsx index 67e17e58..b2f9a18c 100644 --- a/src/frontend/src/features/rooms/components/join/SelectDevice.tsx +++ b/src/frontend/src/features/rooms/components/join/SelectDevice.tsx @@ -7,6 +7,8 @@ import { useTranslation } from 'react-i18next' import { useMediaDeviceSelect } from '@livekit/components-react' import { useMemo } from 'react' import { Select } from '@/primitives/Select' +import { useSnapshot } from 'valtio' +import { permissionsStore } from '@/stores/permissions' type DeviceItems = Array<{ value: string; label: string }> @@ -20,34 +22,23 @@ type SelectDeviceProps = { kind: MediaDeviceKind } -export const SelectDevice = ({ id, onSubmit, kind }: SelectDeviceProps) => { +type SelectDevicePermissionsProps = SelectDeviceProps & { + config: DeviceConfig +} + +const SelectDevicePermissions = ({ + id, + kind, + config, + onSubmit, +}: SelectDevicePermissionsProps) => { const { t } = useTranslation('rooms', { keyPrefix: 'join' }) - const config = useMemo(() => { - switch (kind) { - case 'audioinput': - return { - icon: RiMicLine, - } - case 'videoinput': - return { - icon: RiVideoOnLine, - } - } - }, [kind]) - - const getDefaultSelectedKey = (items: DeviceItems) => { - if (!items || items.length === 0) return - const defaultItem = - items.find((item) => item.value === 'default') || items[0] - return defaultItem.value - } - const { devices: devices, activeDeviceId: activeDeviceId, setActiveMediaDevice: setActiveMediaDevice, - } = useMediaDeviceSelect({ kind, requestPermissions: false }) + } = useMediaDeviceSelect({ kind: kind, requestPermissions: true }) const items: DeviceItems = devices .filter((d) => !!d.deviceId) @@ -64,7 +55,7 @@ export const SelectDevice = ({ id, onSubmit, kind }: SelectDeviceProps) => { items={items} iconComponent={config?.icon} placeholder={t('selectDevice.loading')} - defaultSelectedKey={id || activeDeviceId || getDefaultSelectedKey(items)} + selectedKey={id || activeDeviceId} onSelectionChange={(key) => { onSubmit?.(key as string) setActiveMediaDevice(key as string) @@ -72,3 +63,56 @@ export const SelectDevice = ({ id, onSubmit, kind }: SelectDeviceProps) => { /> ) } + +export const SelectDevice = ({ id, onSubmit, kind }: SelectDeviceProps) => { + const { t } = useTranslation('rooms', { keyPrefix: 'join' }) + + const permissions = useSnapshot(permissionsStore) + + const config = useMemo(() => { + switch (kind) { + case 'audioinput': + return { + icon: RiMicLine, + } + case 'videoinput': + return { + icon: RiVideoOnLine, + } + } + }, [kind]) + + const isPermissionDeniedOrPrompted = useMemo(() => { + if (kind == 'audioinput') { + return permissions.isMicrophoneDenied || permissions.isMicrophonePrompted + } + if (kind == 'videoinput') { + return permissions.isCameraDenied || permissions.isCameraPrompted + } + return false + }, [kind, permissions]) + + if (!config) return null + + if (isPermissionDeniedOrPrompted || permissions.isLoading) { + return ( +