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',
};
}