mirror of
https://github.com/suitenumerique/meet.git
synced 2026-10-10 23:34:38 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3773e43d93 |
+1
-2
@@ -18,6 +18,7 @@ and this project adheres to
|
||||
- ⚡️(backend) reduce domain queries on the application token endpoint
|
||||
- ♻️️️(backend) use a dedicated auth scheme for LiveKit token auth
|
||||
- ♻️(all) stop relying on cookies for the lobby flow
|
||||
- ♿️(frontend) show a visible focus outline on menu items #1797
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -25,8 +26,6 @@ and this project adheres to
|
||||
- 🔒️(frontend) upgrade tiff to fix CVE-2026-4775
|
||||
- 🔒️(backend) bind accepted lobby entries to the current username
|
||||
- 🔒️(backend) sign lobby participant id
|
||||
- 🐛(frontend) omit the default speaker id sent to LiveKit
|
||||
- 🐛(frontend) play the speaker test when no output is picked
|
||||
|
||||
## [1.34.0] - 2026-10-07
|
||||
|
||||
|
||||
@@ -45,7 +45,6 @@ import { userStore } from '@/stores/user'
|
||||
import { WatchMediaDeviceErrors } from './WatchMediaDeviceErrors'
|
||||
import { MeetDevtools } from '@/features/devtools'
|
||||
import { VOICE_AUDIO_CONSTRAINTS } from '@/features/rooms/livekit/utils/constants'
|
||||
import { resolveAudioOutputDeviceId } from '@/features/rooms/utils/resolveAudioOutputDeviceId'
|
||||
|
||||
export const Conference = ({
|
||||
roomId,
|
||||
@@ -121,7 +120,7 @@ export const Conference = ({
|
||||
...VOICE_AUDIO_CONSTRAINTS,
|
||||
},
|
||||
audioOutput: {
|
||||
deviceId: resolveAudioOutputDeviceId(userConfig.audioOutputDeviceId),
|
||||
deviceId: userConfig.audioOutputDeviceId ?? undefined,
|
||||
},
|
||||
}
|
||||
// do not rely on the userConfig object directly as its reference may change on every render
|
||||
|
||||
+5
-8
@@ -4,7 +4,6 @@ import { RiVolumeUpLine } from '@remixicon/react'
|
||||
import { styled } from '@/styled-system/jsx'
|
||||
import { Button } from '@/primitives'
|
||||
import { canTestAudioOutput } from '@/features/rooms/utils/canTestAudioOutput'
|
||||
import { resolveAudioOutputDeviceId } from '@/features/rooms/utils/resolveAudioOutputDeviceId'
|
||||
|
||||
// Speaker test in the audiooutput menu footer (Meet-style UX). Outputs have
|
||||
// no track: the test plays a bundled file through the selected sink, and
|
||||
@@ -67,8 +66,6 @@ export const OutputSoundTester = ({
|
||||
const audioRef = useRef<HTMLAudioElement>(null)
|
||||
const [isPlaying, setIsPlaying] = useState(false)
|
||||
|
||||
const outputId = resolveAudioOutputDeviceId(sinkId)
|
||||
|
||||
const latestSinkIdRef = useRef(sinkId)
|
||||
latestSinkIdRef.current = sinkId
|
||||
|
||||
@@ -82,15 +79,15 @@ export const OutputSoundTester = ({
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (!outputId || !canTestAudioOutput()) return
|
||||
audioRef.current?.setSinkId(outputId).catch(() => {
|
||||
if (!sinkId || !canTestAudioOutput()) return
|
||||
audioRef.current?.setSinkId(sinkId).catch(() => {
|
||||
// Re-routing failed (stale or unplugged device): stop the test rather
|
||||
// than keep playing through the previous sink.
|
||||
if (latestSinkIdRef.current === sinkId) {
|
||||
stopPlayback()
|
||||
}
|
||||
})
|
||||
}, [outputId, sinkId, stopPlayback])
|
||||
}, [sinkId, stopPlayback])
|
||||
|
||||
useEffect(() => {
|
||||
const audio = audioRef.current
|
||||
@@ -111,8 +108,8 @@ export const OutputSoundTester = ({
|
||||
// Confirm routing before starting: a no-op when already routed,
|
||||
// but rejects on a stale device id, so the test never plays
|
||||
// through the wrong sink.
|
||||
if (outputId && canTestAudioOutput()) {
|
||||
await audio.setSinkId(outputId)
|
||||
if (sinkId && canTestAudioOutput()) {
|
||||
await audio.setSinkId(sinkId)
|
||||
}
|
||||
await audio.play()
|
||||
setIsPlaying(true)
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
/**
|
||||
* `'default'` means "use the system output". Firefox has no device with that
|
||||
* id, so setSinkId('default') rejects. Omit it and the browser keeps the OS
|
||||
* default, which is the same result.
|
||||
*/
|
||||
export const resolveAudioOutputDeviceId = (
|
||||
deviceId: string | undefined
|
||||
): string | undefined => {
|
||||
if (!deviceId || deviceId === 'default') return undefined
|
||||
return deviceId
|
||||
}
|
||||
@@ -25,12 +25,15 @@ export const menuRecipe = sva({
|
||||
'&[data-focused]': {
|
||||
color: 'primary.text',
|
||||
backgroundColor: 'primaryDark.100',
|
||||
outline: 'none!',
|
||||
},
|
||||
'&[data-hovered]': {
|
||||
color: 'primary.text',
|
||||
backgroundColor: 'primaryDark.100',
|
||||
outline: 'none!',
|
||||
},
|
||||
'&[data-focus-visible]': {
|
||||
outline: '2px solid',
|
||||
outlineColor: 'focusRing',
|
||||
outlineOffset: '2px',
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -49,6 +52,10 @@ export const menuRecipe = sva({
|
||||
dark: {
|
||||
item: {
|
||||
color: 'white',
|
||||
'&[data-focus-visible]': {
|
||||
outlineColor: 'white!',
|
||||
outlineOffset: '2px!',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user