зеркало из
1
0
Форкнуть 0

[BugFix A11y] video tile a11y updates (#5345)

* add new strings to better announce the state of the participant

* Change files

* remove console

* update string concatenation

* update logic per comment
This commit is contained in:
Donald McEachern 2024-10-21 17:09:38 -07:00 коммит произвёл GitHub
Родитель 365fcfdb0f
Коммит 734c9053e2
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
7 изменённых файлов: 115 добавлений и 6 удалений

Просмотреть файл

@ -0,0 +1,9 @@
{
"type": "minor",
"area": "fix",
"workstream": "A11y",
"comment": "add new strings to better announce the state of the participant",
"packageName": "@azure/communication-react",
"email": "94866715+dmceachernmsft@users.noreply.github.com",
"dependentChangeType": "patch"
}

Просмотреть файл

@ -0,0 +1,9 @@
{
"type": "minor",
"area": "fix",
"workstream": "A11y",
"comment": "add new strings to better announce the state of the participant",
"packageName": "@azure/communication-react",
"email": "94866715+dmceachernmsft@users.noreply.github.com",
"dependentChangeType": "patch"
}

Просмотреть файл

@ -5301,6 +5301,10 @@ export interface VideoTilesOptions {
// @public
export interface VideoTileStrings {
moreOptionsButtonAriaLabel: string;
moreOptionsParticipantHandRaisedAriaLabel: string;
moreOptionsParticipantIsSpeakingAriaLabel: string;
moreOptionsParticipantMutedStateMutedAriaLabel: string;
moreOptionsParticipantMutedStateUnmutedAriaLabel: string;
participantStateHold: string;
participantStateRinging: string;
}

Просмотреть файл

@ -4618,6 +4618,10 @@ export interface VideoTilesOptions {
// @public
export interface VideoTileStrings {
moreOptionsButtonAriaLabel: string;
moreOptionsParticipantHandRaisedAriaLabel: string;
moreOptionsParticipantIsSpeakingAriaLabel: string;
moreOptionsParticipantMutedStateMutedAriaLabel: string;
moreOptionsParticipantMutedStateUnmutedAriaLabel: string;
participantStateHold: string;
participantStateRinging: string;
}

Просмотреть файл

@ -37,6 +37,7 @@ import useLongPress from './utils/useLongPress';
import { moreButtonStyles } from './styles/VideoTile.styles';
import { raiseHandContainerStyles } from './styles/VideoTile.styles';
import { ReactionResources } from '../types/ReactionTypes';
import { formatMoreButtonAriaDescription } from './utils';
/**
* Strings of {@link VideoTile} that can be overridden.
@ -49,6 +50,14 @@ export interface VideoTileStrings {
participantStateRinging: string;
/** String for displaying the Hold state of the remote participant */
participantStateHold: string;
/** String for the announcement of the muted state of the participant when muted */
moreOptionsParticipantMutedStateMutedAriaLabel: string;
/** String for the announcement of the unmuted state of the participant when unmuted */
moreOptionsParticipantMutedStateUnmutedAriaLabel: string;
/** String for the announcement of the participant has their hand raised */
moreOptionsParticipantHandRaisedAriaLabel: string;
/** String for the announcement of whether the participant is speaking or not */
moreOptionsParticipantIsSpeakingAriaLabel: string;
}
/**
@ -213,23 +222,56 @@ const videoTileMoreMenuProps = {
};
const VideoTileMoreOptionsButton = (props: {
contextualMenu?: IContextualMenuProps;
participantDisplayName: string | undefined;
participantState: string | undefined;
participantHandRaised: boolean;
participantIsSpeaking: boolean | undefined;
participantIsMuted: boolean | undefined;
canShowContextMenuButton: boolean;
}): JSX.Element => {
const locale = useLocale();
const locale = useLocale().strings.videoTile;
const theme = useTheme();
const strings = { ...locale.strings.videoTile };
const { contextualMenu, canShowContextMenuButton } = props;
const {
contextualMenu,
canShowContextMenuButton,
participantDisplayName,
participantHandRaised,
participantIsSpeaking,
participantState,
participantIsMuted
} = props;
const [moreButtonAiraDescription, setMoreButtonAriaDescription] = useState<string>('');
useEffect(() => {
setMoreButtonAriaDescription(
formatMoreButtonAriaDescription(
participantDisplayName,
participantIsMuted,
participantHandRaised,
participantState,
participantIsSpeaking,
locale
)
);
}, [
participantDisplayName,
participantHandRaised,
participantIsMuted,
participantIsSpeaking,
participantState,
locale
]);
if (!contextualMenu) {
return <></>;
}
const optionsIcon = canShowContextMenuButton ? 'VideoTileMoreOptions' : undefined;
return (
<IconButton
data-ui-id="video-tile-more-options-button"
ariaLabel={strings?.moreOptionsButtonAriaLabel}
ariaLabel={moreButtonAiraDescription}
styles={moreButtonStyles(theme)}
menuIconProps={videoTileMoreMenuIconProps}
menuProps={{ ...videoTileMoreMenuProps, ...contextualMenu }}
@ -468,6 +510,11 @@ export const VideoTile = (props: VideoTileProps): JSX.Element => {
)}
<VideoTileMoreOptionsButton
contextualMenu={contextualMenu}
participantDisplayName={displayName}
participantHandRaised={!!raisedHand}
participantIsMuted={isMuted}
participantState={participantStateString}
participantIsSpeaking={isSpeaking}
canShowContextMenuButton={canShowContextMenuButton}
/>
</Stack>

Просмотреть файл

@ -5,6 +5,8 @@ import { IIconProps, MessageBarType } from '@fluentui/react';
import { ActiveErrorMessage, ErrorType } from './ErrorBar';
import { _SupportedSpokenLanguage } from '../types';
import { ActiveNotification, NotificationType } from './NotificationStack';
import { VideoTileStrings } from './VideoTile';
import { _formatString } from '@internal/acs-ui-common';
/**
* @private
@ -409,3 +411,33 @@ export const isEnterKeyEventFromCompositionSession = (e: KeyboardEvent): boolean
* @private
*/
export const nullToUndefined = <T>(value: T | null): T | undefined => (value === null ? undefined : value);
/**
* @private
*/
export const formatMoreButtonAriaDescription = (
displayName?: string,
isMuted?: boolean,
isHandRaised?: boolean,
state?: string,
isSpeaking?: boolean,
strings?: VideoTileStrings
): string => {
const mutedState = isMuted
? strings?.moreOptionsParticipantMutedStateMutedAriaLabel
: strings?.moreOptionsParticipantMutedStateUnmutedAriaLabel;
const handRaisedState = isHandRaised ? strings?.moreOptionsParticipantHandRaisedAriaLabel : undefined;
const isSpeakingState = isSpeaking ? strings?.moreOptionsParticipantIsSpeakingAriaLabel : undefined;
const description = strings?.moreOptionsButtonAriaLabel
? _formatString(strings?.moreOptionsButtonAriaLabel, {
displayName: displayName ?? ' ',
isMuted: mutedState ?? ' ',
isHandRaised: handRaisedState ?? ' ',
state: state ?? ' ',
isSpeaking: isSpeakingState ?? ' '
})
: '';
return description;
};

Просмотреть файл

@ -525,7 +525,11 @@
"videoTile": {
"participantStateRinging": "Calling...",
"participantStateHold": "On hold",
"moreOptionsButtonAriaLabel": "More Options"
"moreOptionsButtonAriaLabel": "More Options {displayName} {isMuted} {isHandRaised} {state} {isSpeaking}",
"moreOptionsParticipantMutedStateMutedAriaLabel": "muted",
"moreOptionsParticipantMutedStateUnmutedAriaLabel": "unmuted",
"moreOptionsParticipantHandRaisedAriaLabel": "Hand raised",
"moreOptionsParticipantIsSpeakingAriaLabel": "Speaking"
},
"CameraAndMicrophoneSitePermissionsRequest": {
"primaryText": "Allow {appName} to use your camera and microphone",