diff --git a/src/components/views/rooms/ReadReceiptGroup.tsx b/src/components/views/rooms/ReadReceiptGroup.tsx index 31a2a59dd30..4a2dd8915d2 100644 --- a/src/components/views/rooms/ReadReceiptGroup.tsx +++ b/src/components/views/rooms/ReadReceiptGroup.tsx @@ -53,12 +53,10 @@ interface IAvatarPosition { } function determineAvatarPosition(index: number, count: number, max: number): IAvatarPosition { - const firstVisible = Math.max(0, count - max); - - if (index >= firstVisible) { + if (index < max) { return { hidden: false, - position: index - firstVisible, + position: Math.min(count, max) - index - 1, }; } else { return { @@ -72,8 +70,41 @@ export function ReadReceiptGroup( { readReceipts, readReceiptMap, checkUnmounting, suppressAnimation, isTwelveHour }: Props, ) { const [menuDisplayed, button, openMenu, closeMenu] = useContextMenu(); + + // If we are above MAX_READ_AVATARS, we’ll have to remove a few to have space for the +n count. + const maxAvatars = readReceipts.length > MAX_READ_AVATARS + ? MAX_READ_AVATARS_PLUS_N + : MAX_READ_AVATARS; + + const tooltipMembers: string[] = readReceipts.slice(0, maxAvatars) + .map(it => it.roomMember?.name ?? it.userId); + let tooltipText: string | null; + if (readReceipts.length > MAX_READ_AVATARS) { + tooltipText = _t("%(members)s and more", { + members: tooltipMembers.join(", "), + }); + } else if (readReceipts.length) { + if (tooltipMembers.length > 1) { + tooltipText = _t("%(members)s and %(last)s", { + last: tooltipMembers.pop(), + members: tooltipMembers.join(", "), + }); + } else { + tooltipText = tooltipMembers.join(", "); + } + } + const [{ showTooltip, hideTooltip }, tooltip] = useTooltip({ - label: _t("Seen by %(count)s people", { count: readReceipts.length }), + label: ( + <> +