Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 44 additions & 8 deletions src/components/views/avatars/RoomAvatarView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -37,6 +38,7 @@ export function RoomAvatarView({ room }: RoomAvatarViewProps): JSX.Element {
if (!vm.badgeDecoration) return <RoomAvatar size="32px" room={room} />;

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
Expand All @@ -48,7 +50,7 @@ export function RoomAvatarView({ room }: RoomAvatarViewProps): JSX.Element {
return (
<div className="mx_RoomAvatarView">
<RoomAvatar className={classNames("mx_RoomAvatarView_RoomAvatar", maskClass)} size="32px" room={room} />
{icon}
{label ? <Tooltip label={label}>{icon}</Tooltip> : icon}
</div>
);
}
Expand All @@ -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:
Expand All @@ -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:
Expand All @@ -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:
Expand All @@ -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)}
/>
);
}
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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 <PresenceDecoration presence={presence!} />;
}
}

/**
* 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");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ exports[`<RoomAvatarView /> should render a low priority room decoration 1`] = `
</span>
<svg
aria-label="This is a low priority room"
aria-labelledby="«r0»"
class="mx_RoomAvatarView_icon"
color="var(--cpd-color-icon-tertiary)"
fill="currentColor"
Expand Down Expand Up @@ -92,6 +93,7 @@ exports[`<RoomAvatarView /> should render a public room decoration 1`] = `
</span>
<svg
aria-label="This room is public"
aria-labelledby="«rc»"
class="mx_RoomAvatarView_icon"
color="var(--cpd-color-icon-info-primary)"
fill="currentColor"
Expand Down Expand Up @@ -134,6 +136,7 @@ exports[`<RoomAvatarView /> should render a video room decoration 1`] = `
</span>
<svg
aria-label="This room is a video room"
aria-labelledby="«r6»"
class="mx_RoomAvatarView_icon"
color="var(--cpd-color-icon-tertiary)"
fill="currentColor"
Expand Down
Loading