diff --git a/src/utils/permalinks/ElementPermalinkConstructor.js b/src/utils/permalinks/ElementPermalinkConstructor.js index 7d1096e22d..da7f5797ea 100644 --- a/src/utils/permalinks/ElementPermalinkConstructor.js +++ b/src/utils/permalinks/ElementPermalinkConstructor.js @@ -92,6 +92,11 @@ export default class ElementPermalinkConstructor extends PermalinkConstructor { throw new Error("URL is missing parts"); } + // Split optional query out of last part + const [lastPartMaybeWithQuery] = parts.splice(-1, 1); + const [lastPart, query = ""] = lastPartMaybeWithQuery.split("?"); + parts.push(lastPart); + const entityType = parts[0]; const entity = parts[1]; if (entityType === 'user') { @@ -101,16 +106,9 @@ export default class ElementPermalinkConstructor extends PermalinkConstructor { // Probably a group, no further parsing needed. return PermalinkParts.forGroup(entity); } else if (entityType === 'room') { - // rejoin the rest because v3 events can have slashes (annoyingly) - const eventIdAndQuery = parts.length > 2 ? parts.slice(2).join('/') : ""; - const secondaryParts = eventIdAndQuery.split("?"); - - const eventId = secondaryParts[0]; - const query = secondaryParts.length > 1 ? secondaryParts[1] : ""; - - // TODO: Verify Element works with via args - const via = query.split("via=").filter(p => !!p); - + // Rejoin the rest because v3 events can have slashes (annoyingly) + const eventId = parts.length > 2 ? parts.slice(2).join('/') : ""; + const via = query.split(/&?via=/).filter(p => !!p); return PermalinkParts.forEvent(entity, eventId, via); } else { throw new Error("Unknown entity type in permalink"); diff --git a/test/components/views/messages/TextualBody-test.js b/test/components/views/messages/TextualBody-test.js index 461af19658..d5b80b6756 100644 --- a/test/components/views/messages/TextualBody-test.js +++ b/test/components/views/messages/TextualBody-test.js @@ -242,6 +242,38 @@ describe("", () => { 'rel="noreferrer noopener">event link with text', ); }); + + it("pills appear for room links with vias", () => { + const ev = mkEvent({ + type: "m.room.message", + room: "room_id", + user: "sender", + content: { + body: + "A [room link](https://matrix.to/#/!ZxbRYPQXDXKGmDnJNg:example.com" + + "?via=example.com&via=bob.com) with vias", + msgtype: "m.text", + format: "org.matrix.custom.html", + formatted_body: + "A room link with vias", + }, + event: true, + }); + + const wrapper = mount(); + expect(wrapper.text()).toBe("A !ZxbRYPQXDXKGmDnJNg:example.com with vias"); + const content = wrapper.find(".mx_EventTile_body"); + expect(content.html()).toBe( + '' + + 'A ' + + '!ZxbRYPQXDXKGmDnJNg:example.com with vias', + ); + }); }); it("renders url previews correctly", () => { diff --git a/test/test-utils.js b/test/test-utils.js index c8e623b1d9..839e1d6cd8 100644 --- a/test/test-utils.js +++ b/test/test-utils.js @@ -243,6 +243,7 @@ export function mkStubRoom(roomId = null) { on: jest.fn(), removeListener: jest.fn(), getDMInviter: jest.fn(), + getAvatarUrl: () => 'mxc://avatar.url/room.png', }; }