Skip to content

Commit 4da1f83

Browse files
authored
Fix camera permission requesting when initially opening the app (#273)
1 parent e2b16e8 commit 4da1f83

File tree

2 files changed

+29
-7
lines changed

2 files changed

+29
-7
lines changed

components/livekit/agent-control-bar/agent-control-bar.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ export function AgentControlBar({
149149
<DeviceSelect
150150
size="sm"
151151
kind="audioinput"
152+
requestPermissions={false}
152153
onMediaDeviceError={onMicrophoneDeviceSelectError}
153154
onActiveDeviceChange={handleAudioDeviceChange}
154155
className={cn([
@@ -177,6 +178,7 @@ export function AgentControlBar({
177178
<DeviceSelect
178179
size="sm"
179180
kind="videoinput"
181+
requestPermissions={false}
180182
onMediaDeviceError={onCameraDeviceSelectError}
181183
onActiveDeviceChange={handleVideoDeviceChange}
182184
className={cn([

components/livekit/device-select.tsx

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use client';
22

3+
import { useLayoutEffect, useState } from 'react';
34
import { cva } from 'class-variance-authority';
45
import { LocalAudioTrack, LocalVideoTrack } from 'livekit-client';
56
import { useMaybeRoomContext, useMediaDeviceSelect } from '@livekit/components-react';
@@ -53,27 +54,46 @@ export function DeviceSelect({
5354
}: DeviceSelectProps) {
5455
const size = props.size || 'default';
5556

57+
const [open, setOpen] = useState(false);
58+
const [requestPermissionsState, setRequestPermissionsState] = useState(requestPermissions);
59+
5660
const room = useMaybeRoomContext();
5761
const { devices, activeDeviceId, setActiveMediaDevice } = useMediaDeviceSelect({
5862
kind,
5963
room,
6064
track,
61-
requestPermissions,
65+
requestPermissions: requestPermissionsState,
6266
onError: onMediaDeviceError,
6367
});
68+
69+
// When the select opens, ensure that media devices are re-requested in case when they were last
70+
// requested, permissions were not granted
71+
useLayoutEffect(() => {
72+
if (open) {
73+
setRequestPermissionsState(true);
74+
}
75+
}, [open]);
76+
6477
return (
65-
<Select value={activeDeviceId} onValueChange={setActiveMediaDevice}>
78+
<Select
79+
value={activeDeviceId}
80+
onValueChange={setActiveMediaDevice}
81+
open={open}
82+
onOpenChange={setOpen}
83+
>
6684
<SelectTrigger className={cn(selectVariants({ size }), props.className)}>
6785
{size !== 'sm' && (
6886
<SelectValue className="font-mono text-sm" placeholder={`Select a ${kind}`} />
6987
)}
7088
</SelectTrigger>
7189
<SelectContent>
72-
{devices.map((device) => (
73-
<SelectItem key={device.deviceId} value={device.deviceId} className="font-mono text-xs">
74-
{device.label}
75-
</SelectItem>
76-
))}
90+
{devices
91+
.filter((d) => d.deviceId !== '')
92+
.map((device) => (
93+
<SelectItem key={device.deviceId} value={device.deviceId} className="font-mono text-xs">
94+
{device.label}
95+
</SelectItem>
96+
))}
7797
</SelectContent>
7898
</Select>
7999
);

0 commit comments

Comments
 (0)