♻️(frontend) refactor audio tab to controlled device selection pattern

Convert audio tab device selections to controlled behavior matching
video tab implementation for consistency.

Maintains current component structure without migrating to SelectDevice
component yet, focusing on controlled state pattern alignment first.
This commit is contained in:
lebaudantoine
2025-08-22 01:51:37 +02:00
committed by aleb_the_flash
parent aa09c15ecc
commit 5f32a9e6a3

View File

@@ -25,7 +25,7 @@ export const AudioTab = ({ id }: AudioTabProps) => {
const { localParticipant } = useRoomContext() const { localParticipant } = useRoomContext()
const { const {
userChoices: { noiseReductionEnabled }, userChoices: { noiseReductionEnabled, audioDeviceId, audioOutputDeviceId },
saveAudioInputDeviceId, saveAudioInputDeviceId,
saveNoiseReductionEnabled, saveNoiseReductionEnabled,
saveAudioOutputDeviceId, saveAudioOutputDeviceId,
@@ -33,17 +33,11 @@ export const AudioTab = ({ id }: AudioTabProps) => {
const isSpeaking = useIsSpeaking(localParticipant) const isSpeaking = useIsSpeaking(localParticipant)
const { const { devices: devicesOut, setActiveMediaDevice: setActiveMediaDeviceOut } =
devices: devicesOut, useMediaDeviceSelect({ kind: 'audiooutput' })
activeDeviceId: activeDeviceIdOut,
setActiveMediaDevice: setActiveMediaDeviceOut,
} = useMediaDeviceSelect({ kind: 'audiooutput' })
const { const { devices: devicesIn, setActiveMediaDevice: setActiveMediaDeviceIn } =
devices: devicesIn, useMediaDeviceSelect({ kind: 'audioinput' })
activeDeviceId: activeDeviceIdIn,
setActiveMediaDevice: setActiveMediaDeviceIn,
} = useMediaDeviceSelect({ kind: 'audioinput' })
const itemsOut: DeviceItems = devicesOut.map((d) => ({ const itemsOut: DeviceItems = devicesOut.map((d) => ({
value: d.deviceId, value: d.deviceId,
@@ -68,15 +62,6 @@ export const AudioTab = ({ id }: AudioTabProps) => {
defaultSelectedKey: undefined, defaultSelectedKey: undefined,
} }
// No API to directly query the default audio device; this function heuristically finds it.
// Returns the item with value 'default' if present; otherwise, returns the first item in the list.
const getDefaultSelectedKey = (items: DeviceItems) => {
if (!items || items.length === 0) return
const defaultItem =
items.find((item) => item.value === 'default') || items[0]
return defaultItem.value
}
const noiseReductionAvailable = useNoiseReductionAvailable() const noiseReductionAvailable = useNoiseReductionAvailable()
return ( return (
@@ -86,11 +71,9 @@ export const AudioTab = ({ id }: AudioTabProps) => {
type="select" type="select"
label={t('audio.microphone.label')} label={t('audio.microphone.label')}
items={itemsIn} items={itemsIn}
defaultSelectedKey={ selectedKey={audioDeviceId}
activeDeviceIdIn || getDefaultSelectedKey(itemsIn) onSelectionChange={async (key) => {
} await setActiveMediaDeviceIn(key as string)
onSelectionChange={(key) => {
setActiveMediaDeviceIn(key as string)
saveAudioInputDeviceId(key as string) saveAudioInputDeviceId(key as string)
}} }}
{...disabledProps} {...disabledProps}
@@ -114,11 +97,9 @@ export const AudioTab = ({ id }: AudioTabProps) => {
type="select" type="select"
label={t('audio.speakers.label')} label={t('audio.speakers.label')}
items={itemsOut} items={itemsOut}
defaultSelectedKey={ selectedKey={audioOutputDeviceId}
activeDeviceIdOut || getDefaultSelectedKey(itemsOut) onSelectionChange={async (key) => {
} await setActiveMediaDeviceOut(key as string)
onSelectionChange={(key) => {
setActiveMediaDeviceOut(key as string)
saveAudioOutputDeviceId(key as string) saveAudioOutputDeviceId(key as string)
}} }}
{...disabledProps} {...disabledProps}