Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Stabilize support for MSC3952: intentional mentions #10967

Merged
merged 9 commits into from
Jul 11, 2023
8 changes: 4 additions & 4 deletions src/components/views/rooms/SendMessageComposer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export function attachMentions(
}

// The mentions property *always* gets included to disable legacy push rules.
const mentions: IMentions = (content["org.matrix.msc3952.mentions"] = {});
const mentions: IMentions = (content["m.mentions"] = {});

const userMentions = new Set<string>();
let roomMention = false;
Expand All @@ -100,7 +100,7 @@ export function attachMentions(
userMentions.add(replyToEvent.sender!.userId);
// TODO What do we do if the reply event *doeesn't* have this property?
// Try to fish out replies from the contents?
const userIds = replyToEvent.getContent()["org.matrix.msc3952.mentions"]?.user_ids;
const userIds = replyToEvent.getContent()["m.mentions"]?.user_ids;
if (Array.isArray(userIds)) {
userIds.forEach((userId) => userMentions.add(userId));
}
Expand All @@ -127,7 +127,7 @@ export function attachMentions(
if (editedContent) {
// First, the new event content gets the *full* set of users.
const newContent = content["m.new_content"];
const newMentions: IMentions = (newContent["org.matrix.msc3952.mentions"] = {});
const newMentions: IMentions = (newContent["m.mentions"] = {});

// Only include the users/room if there is any content.
if (userMentions.size) {
Expand All @@ -139,7 +139,7 @@ export function attachMentions(

// Fetch the mentions from the original event and remove any previously
// mentioned users.
const prevMentions = editedContent["org.matrix.msc3952.mentions"];
const prevMentions = editedContent["m.mentions"];
if (Array.isArray(prevMentions?.user_ids)) {
prevMentions!.user_ids.forEach((userId) => userMentions.delete(userId));
}
Expand Down
9 changes: 6 additions & 3 deletions src/settings/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -543,9 +543,12 @@ export const SETTINGS: { [setting: string]: ISetting } = {
displayName: _td("Enable intentional mentions"),
labsGroup: LabGroup.Rooms,
default: false,
controller: new ServerSupportUnstableFeatureController("feature_intentional_mentions", defaultWatchManager, [
["org.matrix.msc3952_intentional_mentions"],
]),
controller: new ServerSupportUnstableFeatureController(
"feature_intentional_mentions",
defaultWatchManager,
[],
"v1.7"
),
},
"useCompactLayout": {
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
Expand Down
2 changes: 1 addition & 1 deletion test/ContentMessages-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ describe("ContentMessages", () => {
expect.objectContaining({
"url": "mxc://server/file",
"msgtype": "m.image",
"org.matrix.msc3952.mentions": {
"m.mentions": {
user_ids: ["@bob:test"],
},
}),
Expand Down
44 changes: 22 additions & 22 deletions test/components/views/rooms/EditMessageComposer-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ describe("<EditMessageComposer/>", () => {
"format": "org.matrix.custom.html",
"formatted_body":
'hey <a href="https://matrix.to/#/@bob:server.org">Bob</a> and <a href="https://matrix.to/#/@charlie:server.org">Charlie</a>',
"org.matrix.msc3952.mentions": {
"m.mentions": {
user_ids: ["@bob:server.org", "@charlie:server.org"],
},
},
Expand Down Expand Up @@ -303,8 +303,8 @@ describe("<EditMessageComposer/>", () => {
const messageContent = mockClient.sendMessage.mock.calls[0][2];

// both content.mentions and new_content.mentions are empty
expect(messageContent["org.matrix.msc3952.mentions"]).toEqual({});
expect(messageContent["m.new_content"]["org.matrix.msc3952.mentions"]).toEqual({});
expect(messageContent["m.mentions"]).toEqual({});
expect(messageContent["m.new_content"]["m.mentions"]).toEqual({});
});

it("should retain mentions in the original message that are not removed by the edit", async () => {
Expand All @@ -319,9 +319,9 @@ describe("<EditMessageComposer/>", () => {
const messageContent = mockClient.sendMessage.mock.calls[0][2];

// no new mentions were added, so nothing in top level mentions
expect(messageContent["org.matrix.msc3952.mentions"]).toEqual({});
expect(messageContent["m.mentions"]).toEqual({});
// bob is still mentioned, charlie removed
expect(messageContent["m.new_content"]["org.matrix.msc3952.mentions"]).toEqual({
expect(messageContent["m.new_content"]["m.mentions"]).toEqual({
user_ids: ["@bob:server.org"],
});
});
Expand All @@ -338,9 +338,9 @@ describe("<EditMessageComposer/>", () => {
const messageContent = mockClient.sendMessage.mock.calls[0][2];

// no new mentions were added, so nothing in top level mentions
expect(messageContent["org.matrix.msc3952.mentions"]).toEqual({});
expect(messageContent["m.mentions"]).toEqual({});
// bob is not longer mentioned in the edited message, so empty mentions in new_content
expect(messageContent["m.new_content"]["org.matrix.msc3952.mentions"]).toEqual({});
expect(messageContent["m.new_content"]["m.mentions"]).toEqual({});
});

it("should add mentions that were added in the edit", async () => {
Expand All @@ -357,10 +357,10 @@ describe("<EditMessageComposer/>", () => {
const messageContent = mockClient.sendMessage.mock.calls[0][2];

// new mention in the edit
expect(messageContent["org.matrix.msc3952.mentions"]).toEqual({
expect(messageContent["m.mentions"]).toEqual({
user_ids: ["@dan:server.org"],
});
expect(messageContent["m.new_content"]["org.matrix.msc3952.mentions"]).toEqual({
expect(messageContent["m.new_content"]["m.mentions"]).toEqual({
user_ids: ["@dan:server.org"],
});
});
Expand All @@ -380,11 +380,11 @@ describe("<EditMessageComposer/>", () => {
const messageContent = mockClient.sendMessage.mock.calls[0][2];

// new mention in the edit
expect(messageContent["org.matrix.msc3952.mentions"]).toEqual({
expect(messageContent["m.mentions"]).toEqual({
user_ids: ["@dan:server.org"],
});
// all mentions in the edited version of the event
expect(messageContent["m.new_content"]["org.matrix.msc3952.mentions"]).toEqual({
expect(messageContent["m.new_content"]["m.mentions"]).toEqual({
user_ids: ["@bob:server.org", "@dan:server.org"],
});
});
Expand All @@ -411,7 +411,7 @@ describe("<EditMessageComposer/>", () => {
event_id: originalEvent.getId(),
},
},
"org.matrix.msc3952.mentions": {
"m.mentions": {
user_ids: [originalEvent.getSender()!],
},
},
Expand All @@ -430,7 +430,7 @@ describe("<EditMessageComposer/>", () => {
event_id: originalEvent.getId(),
},
},
"org.matrix.msc3952.mentions": {
"m.mentions": {
user_ids: [
// sender of event we replied to
originalEvent.getSender()!,
Expand All @@ -457,9 +457,9 @@ describe("<EditMessageComposer/>", () => {
const messageContent = mockClient.sendMessage.mock.calls[0][2];

// no new mentions from edit
expect(messageContent["org.matrix.msc3952.mentions"]).toEqual({});
expect(messageContent["m.mentions"]).toEqual({});
// edited reply still mentions the parent event sender
expect(messageContent["m.new_content"]["org.matrix.msc3952.mentions"]).toEqual({
expect(messageContent["m.new_content"]["m.mentions"]).toEqual({
user_ids: [originalEvent.getSender()],
});
});
Expand All @@ -476,12 +476,12 @@ describe("<EditMessageComposer/>", () => {
const messageContent = mockClient.sendMessage.mock.calls[0][2];

// new mention in edit
expect(messageContent["org.matrix.msc3952.mentions"]).toEqual({
expect(messageContent["m.mentions"]).toEqual({
user_ids: ["@dan:server.org"],
});
// edited reply still mentions the parent event sender
// plus new mention @dan
expect(messageContent["m.new_content"]["org.matrix.msc3952.mentions"]).toEqual({
expect(messageContent["m.new_content"]["m.mentions"]).toEqual({
user_ids: [originalEvent.getSender(), "@dan:server.org"],
});
});
Expand All @@ -497,10 +497,10 @@ describe("<EditMessageComposer/>", () => {
const messageContent = mockClient.sendMessage.mock.calls[0][2];

// no mentions in edit
expect(messageContent["org.matrix.msc3952.mentions"]).toEqual({});
expect(messageContent["m.mentions"]).toEqual({});
// edited reply still mentions the parent event sender
// existing @bob mention removed
expect(messageContent["m.new_content"]["org.matrix.msc3952.mentions"]).toEqual({
expect(messageContent["m.new_content"]["m.mentions"]).toEqual({
user_ids: [originalEvent.getSender()],
});
});
Expand All @@ -518,7 +518,7 @@ describe("<EditMessageComposer/>", () => {
event_id: originalEvent.getId(),
},
},
"org.matrix.msc3952.mentions": {
"m.mentions": {
user_ids: [
// sender of event we replied to
originalEvent.getSender()!,
Expand All @@ -537,9 +537,9 @@ describe("<EditMessageComposer/>", () => {
const messageContent = mockClient.sendMessage.mock.calls[0][2];

// no mentions in edit
expect(messageContent["org.matrix.msc3952.mentions"]).toEqual({});
expect(messageContent["m.mentions"]).toEqual({});
// edited reply still mentions the parent event sender
expect(messageContent["m.new_content"]["org.matrix.msc3952.mentions"]).toEqual({
expect(messageContent["m.new_content"]["m.mentions"]).toEqual({
user_ids: [originalEvent.getSender()],
});
});
Expand Down
58 changes: 29 additions & 29 deletions test/components/views/rooms/SendMessageComposer-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ describe("<SendMessageComposer/>", () => {
const content: IContent = {};
attachMentions("@alice:test", content, model, undefined);
expect(content).toEqual({
"org.matrix.msc3952.mentions": {},
"m.mentions": {},
});
});

Expand All @@ -187,7 +187,7 @@ describe("<SendMessageComposer/>", () => {
const content: IContent = {};
attachMentions("@alice:test", content, model, undefined);
expect(content).toEqual({
"org.matrix.msc3952.mentions": { user_ids: ["@bob:test"] },
"m.mentions": { user_ids: ["@bob:test"] },
});
});

Expand All @@ -198,27 +198,27 @@ describe("<SendMessageComposer/>", () => {
type: "m.room.message",
user: "@bob:test",
room: "!abc:test",
content: { "org.matrix.msc3952.mentions": {} },
content: { "m.mentions": {} },
event: true,
});
let content: IContent = {};
attachMentions("@alice:test", content, model, replyToEvent);
expect(content).toEqual({
"org.matrix.msc3952.mentions": { user_ids: ["@bob:test"] },
"m.mentions": { user_ids: ["@bob:test"] },
});

// It also adds any other mentioned users, but removes yourself.
replyToEvent = mkEvent({
type: "m.room.message",
user: "@bob:test",
room: "!abc:test",
content: { "org.matrix.msc3952.mentions": { user_ids: ["@alice:test", "@charlie:test"] } },
content: { "m.mentions": { user_ids: ["@alice:test", "@charlie:test"] } },
event: true,
});
content = {};
attachMentions("@alice:test", content, model, replyToEvent);
expect(content).toEqual({
"org.matrix.msc3952.mentions": { user_ids: ["@bob:test", "@charlie:test"] },
"m.mentions": { user_ids: ["@bob:test", "@charlie:test"] },
});
});

Expand All @@ -227,7 +227,7 @@ describe("<SendMessageComposer/>", () => {
const content: IContent = {};
attachMentions("@alice:test", content, model, undefined);
expect(content).toEqual({
"org.matrix.msc3952.mentions": { room: true },
"m.mentions": { room: true },
});
});

Expand All @@ -238,13 +238,13 @@ describe("<SendMessageComposer/>", () => {
type: "m.room.message",
user: "@alice:test",
room: "!abc:test",
content: { "org.matrix.msc3952.mentions": { room: true } },
content: { "m.mentions": { room: true } },
event: true,
});
const content: IContent = {};
attachMentions("@alice:test", content, model, replyToEvent);
expect(content).toEqual({
"org.matrix.msc3952.mentions": {},
"m.mentions": {},
});
});

Expand All @@ -256,13 +256,13 @@ describe("<SendMessageComposer/>", () => {
user: "@alice:test",
room: "!abc:test",
// @ts-ignore - Purposefully testing invalid data.
content: { "org.matrix.msc3952.mentions": { user_ids: "@bob:test" } },
content: { "m.mentions": { user_ids: "@bob:test" } },
event: true,
});
const content: IContent = {};
attachMentions("@alice:test", content, model, replyToEvent);
expect(content).toEqual({
"org.matrix.msc3952.mentions": {},
"m.mentions": {},
});
});

Expand All @@ -273,21 +273,21 @@ describe("<SendMessageComposer/>", () => {
const prevContent: IContent = {};
attachMentions("@alice:test", content, model, undefined, prevContent);
expect(content).toEqual({
"org.matrix.msc3952.mentions": {},
"m.new_content": { "org.matrix.msc3952.mentions": {} },
"m.mentions": {},
"m.new_content": { "m.mentions": {} },
});
});

it("mentions do not propagate", () => {
const model = new EditorModel([], partsCreator);
const content: IContent = { "m.new_content": {} };
const prevContent: IContent = {
"org.matrix.msc3952.mentions": { user_ids: ["@bob:test"], room: true },
"m.mentions": { user_ids: ["@bob:test"], room: true },
};
attachMentions("@alice:test", content, model, undefined, prevContent);
expect(content).toEqual({
"org.matrix.msc3952.mentions": {},
"m.new_content": { "org.matrix.msc3952.mentions": {} },
"m.mentions": {},
"m.new_content": { "m.mentions": {} },
});
});

Expand All @@ -297,19 +297,19 @@ describe("<SendMessageComposer/>", () => {
const prevContent: IContent = {};
attachMentions("@alice:test", content, model, undefined, prevContent);
expect(content).toEqual({
"org.matrix.msc3952.mentions": { user_ids: ["@bob:test"] },
"m.new_content": { "org.matrix.msc3952.mentions": { user_ids: ["@bob:test"] } },
"m.mentions": { user_ids: ["@bob:test"] },
"m.new_content": { "m.mentions": { user_ids: ["@bob:test"] } },
});
});

it("test prev user mentions", () => {
const model = new EditorModel([partsCreator.userPill("Bob", "@bob:test")], partsCreator);
const content: IContent = { "m.new_content": {} };
const prevContent: IContent = { "org.matrix.msc3952.mentions": { user_ids: ["@bob:test"] } };
const prevContent: IContent = { "m.mentions": { user_ids: ["@bob:test"] } };
attachMentions("@alice:test", content, model, undefined, prevContent);
expect(content).toEqual({
"org.matrix.msc3952.mentions": {},
"m.new_content": { "org.matrix.msc3952.mentions": { user_ids: ["@bob:test"] } },
"m.mentions": {},
"m.new_content": { "m.mentions": { user_ids: ["@bob:test"] } },
});
});

Expand All @@ -319,19 +319,19 @@ describe("<SendMessageComposer/>", () => {
const prevContent: IContent = {};
attachMentions("@alice:test", content, model, undefined, prevContent);
expect(content).toEqual({
"org.matrix.msc3952.mentions": { room: true },
"m.new_content": { "org.matrix.msc3952.mentions": { room: true } },
"m.mentions": { room: true },
"m.new_content": { "m.mentions": { room: true } },
});
});

it("test prev room mention", () => {
const model = new EditorModel([partsCreator.atRoomPill("@room")], partsCreator);
const content: IContent = { "m.new_content": {} };
const prevContent: IContent = { "org.matrix.msc3952.mentions": { room: true } };
const prevContent: IContent = { "m.mentions": { room: true } };
attachMentions("@alice:test", content, model, undefined, prevContent);
expect(content).toEqual({
"org.matrix.msc3952.mentions": {},
"m.new_content": { "org.matrix.msc3952.mentions": { room: true } },
"m.mentions": {},
"m.new_content": { "m.mentions": { room: true } },
});
});

Expand All @@ -340,11 +340,11 @@ describe("<SendMessageComposer/>", () => {
const model = new EditorModel([], partsCreator);
const content: IContent = { "m.new_content": {} };
// @ts-ignore - Purposefully testing invalid data.
const prevContent: IContent = { "org.matrix.msc3952.mentions": { user_ids: "@bob:test" } };
const prevContent: IContent = { "m.mentions": { user_ids: "@bob:test" } };
attachMentions("@alice:test", content, model, undefined, prevContent);
expect(content).toEqual({
"org.matrix.msc3952.mentions": {},
"m.new_content": { "org.matrix.msc3952.mentions": {} },
"m.mentions": {},
"m.new_content": { "m.mentions": {} },
});
});
});
Expand Down
Loading