diff --git a/src/components/views/avatars/RoomAvatarView.tsx b/src/components/views/avatars/RoomAvatarView.tsx index 1f85ee9512d..f75b214063f 100644 --- a/src/components/views/avatars/RoomAvatarView.tsx +++ b/src/components/views/avatars/RoomAvatarView.tsx @@ -14,6 +14,7 @@ import OnlineOrUnavailableIcon from "@vector-im/compound-design-tokens/assets/we import OfflineIcon from "@vector-im/compound-design-tokens/assets/web/icons/presence-outline-8x8"; import BusyIcon from "@vector-im/compound-design-tokens/assets/web/icons/presence-strikethrough-8x8"; import classNames from "classnames"; +import { Tooltip } from "@vector-im/compound-web"; import RoomAvatar from "./RoomAvatar"; import { AvatarBadgeDecoration, useRoomAvatarViewModel } from "../../viewmodels/avatars/RoomAvatarViewModel"; @@ -37,6 +38,7 @@ export function RoomAvatarView({ room }: RoomAvatarViewProps): JSX.Element { if (!vm.badgeDecoration) return ; const icon = getAvatarDecoration(vm.badgeDecoration, vm.presence); + const label = getDecorationLabel(vm.badgeDecoration, vm.presence); // Presence indicator and video/public icons don't have the same size // We use different masks @@ -48,7 +50,7 @@ export function RoomAvatarView({ room }: RoomAvatarViewProps): JSX.Element { return (
- {icon} + {label ? {icon} : icon}
); } @@ -72,7 +74,7 @@ function PresenceDecoration({ presence }: PresenceDecorationProps): JSX.Element height="8px" className="mx_RoomAvatarView_PresenceDecoration" color="var(--cpd-color-icon-accent-primary)" - aria-label={_t("presence|online")} + aria-label={getPresenceLabel(presence)} /> ); case Presence.Away: @@ -82,7 +84,7 @@ function PresenceDecoration({ presence }: PresenceDecorationProps): JSX.Element height="8px" className="mx_RoomAvatarView_PresenceDecoration" color="var(--cpd-color-icon-quaternary)" - aria-label={_t("presence|away")} + aria-label={getPresenceLabel(presence)} /> ); case Presence.Offline: @@ -92,7 +94,7 @@ function PresenceDecoration({ presence }: PresenceDecorationProps): JSX.Element height="8px" className="mx_RoomAvatarView_PresenceDecoration" color="var(--cpd-color-icon-tertiary)" - aria-label={_t("presence|offline")} + aria-label={getPresenceLabel(presence)} /> ); case Presence.Busy: @@ -102,7 +104,7 @@ function PresenceDecoration({ presence }: PresenceDecorationProps): JSX.Element height="8px" className="mx_RoomAvatarView_PresenceDecoration" color="var(--cpd-color-icon-tertiary)" - aria-label={_t("presence|busy")} + aria-label={getPresenceLabel(presence)} /> ); } @@ -116,7 +118,7 @@ function getAvatarDecoration(decoration: AvatarBadgeDecoration, presence: Presen height="16px" className="mx_RoomAvatarView_icon" color="var(--cpd-color-icon-tertiary)" - aria-label={_t("room|room_is_low_priority")} + aria-label={getDecorationLabel(decoration, presence)} /> ); } else if (decoration === AvatarBadgeDecoration.VideoRoom) { @@ -126,7 +128,7 @@ function getAvatarDecoration(decoration: AvatarBadgeDecoration, presence: Presen height="16px" className="mx_RoomAvatarView_icon" color="var(--cpd-color-icon-tertiary)" - aria-label={_t("room|video_room")} + aria-label={getDecorationLabel(decoration, presence)} /> ); } else if (decoration === AvatarBadgeDecoration.PublicRoom) { @@ -136,10 +138,44 @@ function getAvatarDecoration(decoration: AvatarBadgeDecoration, presence: Presen height="16px" className="mx_RoomAvatarView_icon" color="var(--cpd-color-icon-info-primary)" - aria-label={_t("room|header|room_is_public")} + aria-label={getDecorationLabel(decoration, presence)} /> ); } else if (decoration === AvatarBadgeDecoration.Presence) { return ; } } + +/** + * Get the label for the avatar decoration. + * This is used for the tooltip and a11y label. + */ +function getDecorationLabel(decoration: AvatarBadgeDecoration, presence: Presence | null): string | undefined { + switch (decoration) { + case AvatarBadgeDecoration.LowPriority: + return _t("room|room_is_low_priority"); + case AvatarBadgeDecoration.VideoRoom: + return _t("room|video_room"); + case AvatarBadgeDecoration.PublicRoom: + return _t("room|header|room_is_public"); + case AvatarBadgeDecoration.Presence: + return getPresenceLabel(presence!); + } +} + +/** + * Get the label for the presence. + * This is used for the tooltip and a11y label. + */ +function getPresenceLabel(presence: Presence): string { + switch (presence) { + case Presence.Online: + return _t("presence|online"); + case Presence.Away: + return _t("presence|away"); + case Presence.Offline: + return _t("presence|offline"); + case Presence.Busy: + return _t("presence|busy"); + } +} diff --git a/test/unit-tests/components/views/avatars/__snapshots__/RoomAvatarView-test.tsx.snap b/test/unit-tests/components/views/avatars/__snapshots__/RoomAvatarView-test.tsx.snap index 5a3fa24ccca..2acfaf1f00d 100644 --- a/test/unit-tests/components/views/avatars/__snapshots__/RoomAvatarView-test.tsx.snap +++ b/test/unit-tests/components/views/avatars/__snapshots__/RoomAvatarView-test.tsx.snap @@ -50,6 +50,7 @@ exports[` should render a low priority room decoration 1`] = ` should render a public room decoration 1`] = ` should render a video room decoration 1`] = `