♿️(frontend) improve background effect announcements
ensure sr announces clear and virtual background state
This commit is contained in:
@@ -14,6 +14,7 @@ and this project adheres to
|
|||||||
- ♿️(frontend) improve participants toggle a11y label #880
|
- ♿️(frontend) improve participants toggle a11y label #880
|
||||||
- ♿️(frontend) make carousel image decorative #871
|
- ♿️(frontend) make carousel image decorative #871
|
||||||
- ♿️(frontend) reactions are now vocalized and configurable #849
|
- ♿️(frontend) reactions are now vocalized and configurable #849
|
||||||
|
- ♿️(frontend) improve background effect announcements #879
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
|||||||
@@ -56,11 +56,11 @@ export const EffectsConfiguration = ({
|
|||||||
const [processorPending, setProcessorPending] = useState(false)
|
const [processorPending, setProcessorPending] = useState(false)
|
||||||
const processorPendingReveal = useSyncAfterDelay(processorPending)
|
const processorPendingReveal = useSyncAfterDelay(processorPending)
|
||||||
const hasFunnyEffectsAccess = useHasFunnyEffectsAccess()
|
const hasFunnyEffectsAccess = useHasFunnyEffectsAccess()
|
||||||
const [blurStatusMessage, setBlurStatusMessage] = useState('')
|
const [effectStatusMessage, setEffectStatusMessage] = useState('')
|
||||||
const blurAnnouncementTimeout = useRef<ReturnType<typeof setTimeout> | null>(
|
const effectAnnouncementTimeout = useRef<ReturnType<
|
||||||
null
|
typeof setTimeout
|
||||||
)
|
> | null>(null)
|
||||||
const blurAnnouncementId = useRef(0)
|
const effectAnnouncementId = useRef(0)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const videoElement = videoRef.current
|
const videoElement = videoRef.current
|
||||||
@@ -89,27 +89,27 @@ export const EffectsConfiguration = ({
|
|||||||
|
|
||||||
useEffect(
|
useEffect(
|
||||||
() => () => {
|
() => () => {
|
||||||
if (blurAnnouncementTimeout.current) {
|
if (effectAnnouncementTimeout.current) {
|
||||||
clearTimeout(blurAnnouncementTimeout.current)
|
clearTimeout(effectAnnouncementTimeout.current)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[]
|
[]
|
||||||
)
|
)
|
||||||
|
|
||||||
const announceBlurStatusMessage = (message: string) => {
|
const announceEffectStatusMessage = (message: string) => {
|
||||||
blurAnnouncementId.current += 1
|
effectAnnouncementId.current += 1
|
||||||
const currentId = blurAnnouncementId.current
|
const currentId = effectAnnouncementId.current
|
||||||
|
|
||||||
if (blurAnnouncementTimeout.current) {
|
if (effectAnnouncementTimeout.current) {
|
||||||
clearTimeout(blurAnnouncementTimeout.current)
|
clearTimeout(effectAnnouncementTimeout.current)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear the region first so screen readers drop queued announcements.
|
// Clear the region first so screen readers drop queued announcements.
|
||||||
setBlurStatusMessage('')
|
setEffectStatusMessage('')
|
||||||
|
|
||||||
blurAnnouncementTimeout.current = setTimeout(() => {
|
effectAnnouncementTimeout.current = setTimeout(() => {
|
||||||
if (currentId !== blurAnnouncementId.current) return
|
if (currentId !== effectAnnouncementId.current) return
|
||||||
setBlurStatusMessage(message)
|
setEffectStatusMessage(message)
|
||||||
}, 80)
|
}, 80)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,25 +118,42 @@ export const EffectsConfiguration = ({
|
|||||||
onSubmit?.(undefined)
|
onSubmit?.(undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateBlurStatusMessage = (
|
const getVirtualBackgroundName = (imagePath?: string) => {
|
||||||
|
if (!imagePath) return ''
|
||||||
|
const match = imagePath.match(/\/backgrounds\/(\d+)\.jpg$/)
|
||||||
|
if (!match) return ''
|
||||||
|
const index = Number(match[1]) - 1
|
||||||
|
if (Number.isNaN(index)) return ''
|
||||||
|
return t(`virtual.descriptions.${index}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateEffectStatusMessage = (
|
||||||
type: ProcessorType,
|
type: ProcessorType,
|
||||||
options: BackgroundOptions,
|
options: BackgroundOptions,
|
||||||
wasSelectedBeforeToggle: boolean
|
wasSelectedBeforeToggle: boolean
|
||||||
) => {
|
) => {
|
||||||
if (type !== ProcessorType.BLUR) return
|
|
||||||
|
|
||||||
let message = ''
|
|
||||||
|
|
||||||
if (wasSelectedBeforeToggle) {
|
if (wasSelectedBeforeToggle) {
|
||||||
message = t('blur.status.none')
|
announceEffectStatusMessage(t('blur.status.none'))
|
||||||
} else if (options.blurRadius === BlurRadius.LIGHT) {
|
return
|
||||||
message = t('blur.status.light')
|
|
||||||
} else if (options.blurRadius === BlurRadius.NORMAL) {
|
|
||||||
message = t('blur.status.strong')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message) {
|
if (type === ProcessorType.BLUR) {
|
||||||
announceBlurStatusMessage(message)
|
const message =
|
||||||
|
options.blurRadius === BlurRadius.LIGHT
|
||||||
|
? t('blur.status.light')
|
||||||
|
: t('blur.status.strong')
|
||||||
|
announceEffectStatusMessage(message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === ProcessorType.VIRTUAL) {
|
||||||
|
const backgroundName = getVirtualBackgroundName(options.imagePath)
|
||||||
|
if (backgroundName) {
|
||||||
|
announceEffectStatusMessage(
|
||||||
|
`${t('virtual.selectedLabel')} ${backgroundName}`
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,7 +217,7 @@ export const EffectsConfiguration = ({
|
|||||||
onSubmit?.(processor)
|
onSubmit?.(processor)
|
||||||
}
|
}
|
||||||
|
|
||||||
updateBlurStatusMessage(type, options, wasSelectedBeforeToggle)
|
updateEffectStatusMessage(type, options, wasSelectedBeforeToggle)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error applying effect:', error)
|
console.error('Error applying effect:', error)
|
||||||
} finally {
|
} finally {
|
||||||
@@ -407,7 +424,7 @@ export const EffectsConfiguration = ({
|
|||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</div>
|
</div>
|
||||||
<div aria-live="polite" className="sr-only">
|
<div aria-live="polite" className="sr-only">
|
||||||
{blurStatusMessage}
|
{effectStatusMessage}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|||||||
Reference in New Issue
Block a user