events: Add method to add mentions instead of replacing them

This commit is contained in:
Kévin Commaille 2023-08-21 17:44:40 +02:00 committed by Kévin Commaille
parent b2b4c81645
commit 7dee1d64be
2 changed files with 64 additions and 0 deletions

View File

@ -350,6 +350,10 @@ impl RoomMessageEventContent {
/// `m.new_content` so only new mentions will trigger a notification. As such, this needs to be
/// called after [`Self::make_replacement()`].
///
/// It is not recommended to call this method after one that sets mentions automatically, like
/// [`Self::make_reply_to()`] as these will be overwritten. [`Self::add_mentions()`] should be
/// used instead.
///
/// [mentions]: https://spec.matrix.org/latest/client-server-api/#user-and-room-mentions
pub fn set_mentions(mut self, mentions: Mentions) -> Self {
if let Some(Relation::Replacement(replacement)) = &mut self.relates_to {
@ -381,6 +385,28 @@ impl RoomMessageEventContent {
self
}
/// Add the given [mentions] to this event.
///
/// If no [`Mentions`] was set on this events, this sets it. Otherwise, this updates the current
/// mentions by extending the previous `user_ids` with the new ones, and applies a logical OR to
/// the values of `room`.
///
/// This is recommended over [`Self::set_mentions()`] to avoid to overwrite any mentions set
/// automatically by another method, like [`Self::make_reply_to()`]. However, this method has no
/// special support for replacements.
///
/// [mentions]: https://spec.matrix.org/latest/client-server-api/#user-and-room-mentions
pub fn add_mentions(mut self, mentions: Mentions) -> Self {
if let Some(m) = &mut self.mentions {
m.user_ids.extend(mentions.user_ids);
m.room |= mentions.room;
} else {
self.mentions = Some(mentions);
}
self
}
/// Returns a reference to the `msgtype` string.
///
/// If you want to access the message type-specific data rather than the message type itself,

View File

@ -271,6 +271,7 @@ fn escape_tags_in_plain_reply_body() {
ForwardThread::Yes,
AddMentions::No,
);
assert_matches!(second_message.mentions, None);
assert_matches!(
first_message.content.msgtype,
@ -406,6 +407,43 @@ fn reply_sanitize() {
);
}
#[test]
fn reply_add_mentions() {
let user = owned_user_id!("@user:example.org");
let friend = owned_user_id!("@friend:example.org");
let other_friend = owned_user_id!("@other_friend:example.org");
let mut first_message_content = RoomMessageEventContent::text_plain("My friend!");
first_message_content.mentions = Some(Mentions::with_user_ids([friend.clone()]));
let first_message = OriginalRoomMessageEvent {
content: first_message_content,
event_id: owned_event_id!("$143273582443PhrSn"),
origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(10_000)),
room_id: owned_room_id!("!testroomid:example.org"),
sender: user.clone(),
unsigned: MessageLikeUnsigned::default(),
};
let mut second_message = RoomMessageEventContent::text_plain("User! Other friend!")
.make_reply_to(&first_message, ForwardThread::Yes, AddMentions::Yes);
let mentions = second_message.mentions.clone().unwrap();
assert_eq!(mentions.user_ids, [friend.clone(), user.clone()].into());
assert!(!mentions.room);
second_message =
second_message.add_mentions(Mentions::with_user_ids([user.clone(), other_friend.clone()]));
let mentions = second_message.mentions.clone().unwrap();
assert_eq!(mentions.user_ids, [friend.clone(), other_friend.clone(), user.clone()].into());
assert!(!mentions.room);
second_message = second_message.add_mentions(Mentions::with_room_mention());
let mentions = second_message.mentions.unwrap();
assert_eq!(mentions.user_ids, [friend, other_friend, user].into());
assert!(mentions.room);
}
#[test]
fn make_replacement_no_reply() {
let content = RoomMessageEventContent::text_html(