diff --git a/src/components/views/elements/EventListSummary.tsx b/src/components/views/elements/EventListSummary.tsx index 4436b2d9bf7..60288fb2f56 100644 --- a/src/components/views/elements/EventListSummary.tsx +++ b/src/components/views/elements/EventListSummary.tsx @@ -507,39 +507,36 @@ export default class EventListSummary extends React.Component { eventsToRender.forEach((e, index) => { const type = e.getType(); - let userId = e.getSender(); - if (type === EventType.RoomMember) { - userId = e.getStateKey(); + let userKey = e.getSender()!; + if (type === EventType.RoomThirdPartyInvite) { + userKey = e.getContent().display_name; + } else if (type === EventType.RoomMember) { + userKey = e.getStateKey(); } else if (e.isRedacted()) { - userId = e.getUnsigned()?.redacted_because?.sender; + userKey = e.getUnsigned()?.redacted_because?.sender; } // Initialise a user's events - if (!userEvents[userId]) { - userEvents[userId] = []; + if (!userEvents[userKey]) { + userEvents[userKey] = []; } - let displayName = userId; - if (type === EventType.RoomThirdPartyInvite) { - displayName = e.getContent().display_name; - if (e.sender) { - latestUserAvatarMember.set(userId, e.sender); - } - } else if (e.isRedacted()) { - const sender = this.context?.room.getMember(userId); + let displayName = userKey; + if (e.isRedacted()) { + const sender = this.context?.room?.getMember(userKey); if (sender) { displayName = sender.name; - latestUserAvatarMember.set(userId, sender); + latestUserAvatarMember.set(userKey, sender); } } else if (e.target && TARGET_AS_DISPLAY_NAME_EVENTS.includes(type as EventType)) { displayName = e.target.name; - latestUserAvatarMember.set(userId, e.target); - } else if (e.sender) { + latestUserAvatarMember.set(userKey, e.target); + } else if (e.sender && type !== EventType.RoomThirdPartyInvite) { displayName = e.sender.name; - latestUserAvatarMember.set(userId, e.sender); + latestUserAvatarMember.set(userKey, e.sender); } - userEvents[userId].push({ + userEvents[userKey].push({ mxEvent: e, displayName, index: index, diff --git a/test/components/views/elements/EventListSummary-test.tsx b/test/components/views/elements/EventListSummary-test.tsx index ebf799e3f22..6f8c5fd7c8f 100644 --- a/test/components/views/elements/EventListSummary-test.tsx +++ b/test/components/views/elements/EventListSummary-test.tsx @@ -21,6 +21,7 @@ import { MatrixEvent, RoomMember } from "matrix-js-sdk/src/matrix"; import { getMockClientWithEventEmitter, + mkEvent, mkMembership, mockClientMethodsUser, unmockClientPeg, @@ -100,7 +101,7 @@ describe("EventListSummary", function () { // is created by replacing the first "$" in userIdTemplate with `i` for // `i = 0 .. n`. const generateEventsForUsers = (userIdTemplate, n, events) => { - let eventsForUsers = []; + let eventsForUsers: MatrixEvent[] = []; let userId = ""; for (let i = 0; i < n; i++) { userId = userIdTemplate.replace("$", i); @@ -656,4 +657,56 @@ describe("EventListSummary", function () { expect(summaryText).toBe("user_0, user_1 and 18 others joined"); }); + + it("should not blindly group 3pid invites and treat them as distinct users instead", () => { + const events = [ + mkEvent({ + event: true, + skey: "randomstring1", + user: "@user1:server", + type: "m.room.third_party_invite", + content: { + display_name: "n...@d...", + key_validity_url: "https://blah", + public_key: "public_key", + }, + }), + mkEvent({ + event: true, + skey: "randomstring2", + user: "@user1:server", + type: "m.room.third_party_invite", + content: { + display_name: "n...@d...", + key_validity_url: "https://blah", + public_key: "public_key", + }, + }), + mkEvent({ + event: true, + skey: "randomstring3", + user: "@user1:server", + type: "m.room.third_party_invite", + content: { + display_name: "d...@w...", + key_validity_url: "https://blah", + public_key: "public_key", + }, + }), + ]; + + const props = { + events: events, + children: generateTiles(events), + summaryLength: 2, + avatarsMaxLength: 5, + threshold: 3, + }; + + const wrapper = renderComponent(props); + const summary = wrapper.find(".mx_GenericEventListSummary_summary"); + const summaryText = summary.text(); + + expect(summaryText).toBe("n...@d... was invited 2 times, d...@w... was invited"); + }); });