diff --git a/src/components/views/rooms/ReadReceiptGroup.tsx b/src/components/views/rooms/ReadReceiptGroup.tsx index 31a2a59dd306..098c60af48bf 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, }; } else { return { @@ -72,8 +70,42 @@ 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) { + const last = tooltipMembers.pop(); + if (last) { + tooltipText = _t("%(members)s and %(last)s", { + members: tooltipMembers.join(", "), + last: last, + }); + } else { + tooltipText = tooltipMembers.join(", "); + } + } + const [{ showTooltip, hideTooltip }, tooltip] = useTooltip({ - label: _t("Seen by %(count)s people", { count: readReceipts.length }), + label: ( + <> +