From 1d23cb889ab4a87c01c5b74c15890f6735855f17 Mon Sep 17 00:00:00 2001 From: Cyril Date: Mon, 2 Mar 2026 12:23:22 +0100 Subject: [PATCH] =?UTF-8?q?=E2=99=BF=EF=B8=8F(frontend)=20announce=20mic/c?= =?UTF-8?q?amera=20state=20for=20screen=20readers=20on=20shortcut?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit announce "Microphone/Camera turned on/off" when toggling via keyboard shortcut so screen reader users get feedback --- CHANGELOG.md | 1 + .../components/controls/Device/ToggleDevice.tsx | 17 ++++++++++++++++- src/frontend/src/locales/de/rooms.json | 4 ++++ src/frontend/src/locales/en/rooms.json | 4 ++++ src/frontend/src/locales/fr/rooms.json | 4 ++++ src/frontend/src/locales/nl/rooms.json | 4 ++++ 6 files changed, 33 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bdc80dd..20b6c37d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ and this project adheres to - ⬆️(python) bump minimal required python version to 3.13 #1033 - ♿️(frontend) improve accessibility of the IntroSlider carousel #1026 - ♿️(frontend) add skip link component for keyboard navigation #1019 +- ♿️(frontend) announce mic/camera state to SR on shortcut toggle #1052 ### Fixed diff --git a/src/frontend/src/features/rooms/livekit/components/controls/Device/ToggleDevice.tsx b/src/frontend/src/features/rooms/livekit/components/controls/Device/ToggleDevice.tsx index 96359e1b..5ec7b8a0 100644 --- a/src/frontend/src/features/rooms/livekit/components/controls/Device/ToggleDevice.tsx +++ b/src/frontend/src/features/rooms/livekit/components/controls/Device/ToggleDevice.tsx @@ -1,5 +1,6 @@ import { ToggleButton } from '@/primitives' import { useRegisterKeyboardShortcut } from '@/features/shortcuts/useRegisterKeyboardShortcut' +import { useScreenReaderAnnounce } from '@/hooks/useScreenReaderAnnounce' import { useMemo, useState } from 'react' import { appendShortcutLabel } from '@/features/shortcuts/utils' import { useTranslation } from 'react-i18next' @@ -87,10 +88,24 @@ export const ToggleDevice = ({ const deviceIcons = useDeviceIcons(kind) const cannotUseDevice = useCannotUseDevice(kind) const deviceShortcut = useDeviceShortcut(kind) + const announce = useScreenReaderAnnounce() useRegisterKeyboardShortcut({ id: deviceShortcut?.id, - handler: async () => await toggle(), + handler: async () => { + const nextState = !enabled + try { + const didChange = await toggle(nextState) + if (didChange === false) return + + const message = t(nextState ? 'turnedOn' : 'turnedOff', { + keyPrefix: `selectDevice.${kind}`, + }) + announce(message, 'assertive') + } catch { + // no announce + } + }, isDisabled: cannotUseDevice, }) diff --git a/src/frontend/src/locales/de/rooms.json b/src/frontend/src/locales/de/rooms.json index 76bdf8de..70ff94cd 100644 --- a/src/frontend/src/locales/de/rooms.json +++ b/src/frontend/src/locales/de/rooms.json @@ -22,6 +22,8 @@ "permissionsNeeded": "Kamera auswählen - genehmigung erforderlich", "disable": "Kamera deaktivieren", "enable": "Kamera aktivieren", + "turnedOff": "Kamera deaktiviert", + "turnedOn": "Kamera aktiviert", "label": "Kamera", "placeholder": "Kamera aktivieren, um die Vorschau zu sehen" }, @@ -30,6 +32,8 @@ "permissionsNeeded": "Mikrofon auswählen - genehmigung erforderlich", "disable": "Mikrofon deaktivieren", "enable": "Mikrofon aktivieren", + "turnedOff": "Mikrofon deaktiviert", + "turnedOn": "Mikrofon aktiviert", "label": "Mikrofon" }, "audiooutput": { diff --git a/src/frontend/src/locales/en/rooms.json b/src/frontend/src/locales/en/rooms.json index e32fc113..390cdb9b 100644 --- a/src/frontend/src/locales/en/rooms.json +++ b/src/frontend/src/locales/en/rooms.json @@ -22,6 +22,8 @@ "permissionsNeeded": "Select camera - permission needed", "disable": "Disable camera", "enable": "Enable camera", + "turnedOff": "Camera turned off", + "turnedOn": "Camera turned on", "label": "Camera", "placeholder": "Enable camera to see the preview" }, @@ -30,6 +32,8 @@ "permissionsNeeded": "Select microphone - permission needed", "disable": "Disable microphone", "enable": "Enable microphone", + "turnedOff": "Microphone turned off", + "turnedOn": "Microphone turned on", "label": "Microphone" }, "audiooutput": { diff --git a/src/frontend/src/locales/fr/rooms.json b/src/frontend/src/locales/fr/rooms.json index 6aaddddd..f8bbc3bd 100644 --- a/src/frontend/src/locales/fr/rooms.json +++ b/src/frontend/src/locales/fr/rooms.json @@ -22,6 +22,8 @@ "permissionsNeeded": "Choisir la webcam - autorisations nécessaires", "disable": "Désactiver la webcam", "enable": "Activer la webcam", + "turnedOff": "Webcam désactivée", + "turnedOn": "Webcam activée", "label": "Webcam", "placeholder": "Activez la webcam pour prévisualiser l'affichage" }, @@ -30,6 +32,8 @@ "permissionsNeeded": "Choisir le micro - autorisations nécessaires", "disable": "Désactiver le micro", "enable": "Activer le micro", + "turnedOff": "Micro désactivé", + "turnedOn": "Micro activé", "label": "Microphone" }, "audiooutput": { diff --git a/src/frontend/src/locales/nl/rooms.json b/src/frontend/src/locales/nl/rooms.json index f7e778b7..c635f1dd 100644 --- a/src/frontend/src/locales/nl/rooms.json +++ b/src/frontend/src/locales/nl/rooms.json @@ -22,6 +22,8 @@ "permissionsNeeded": "Selecteer camera - Toestemming vereist", "disable": "Camera uitschakelen", "enable": "Camera inschakelen", + "turnedOff": "Camera uitgeschakeld", + "turnedOn": "Camera ingeschakeld", "label": "Camera", "placeholder": "Schakel de camera in om de preview te zien" }, @@ -30,6 +32,8 @@ "permissionsNeeded": "Selecteer microfoon - Toestemming vereist", "disable": "Microfoon dempen", "enable": "Microfoon dempen opheffen", + "turnedOff": "Microfoon uitgeschakeld", + "turnedOn": "Microfoon ingeschakeld", "label": "Microfoon" }, "audiooutput": {