fix(timeline): correctly use the bundled event id when handling replacements

This commit is contained in:
Benjamin Bouvier
2025-06-09 17:00:33 +02:00
parent 378f50d8b5
commit ca0fc3cf6d
3 changed files with 50 additions and 50 deletions

View File

@@ -638,6 +638,9 @@ fn resolve_edits(
}
/// Apply the selected edit to the given EventTimelineItem.
///
/// Returns true if the edit was applied, false otherwise (because the edit and
/// original timeline item types didn't match, for instance).
fn edit_item(item: &mut Cow<'_, EventTimelineItem>, edit: PendingEdit) -> bool {
let PendingEdit { kind: edit_kind, edit_json, encryption_info } = edit;

View File

@@ -376,28 +376,26 @@ impl TimelineMetadata {
// Record the bundled edit in the aggregations set, if any.
if let Some(ctx) = remote_ctx {
if let Some(new_content) = extract_poll_edit_content(ctx.relations) {
// It is replacing the current event.
if let Some(edit_event_id) =
ctx.raw_event.get_field::<OwnedEventId>("event_id").ok().flatten()
{
let edit_json = extract_bundled_edit_event_json(ctx.raw_event);
let aggregation = Aggregation::new(
TimelineEventItemId::EventId(edit_event_id),
AggregationKind::Edit(PendingEdit {
kind: PendingEditKind::Poll(Replacement::new(
ctx.event_id.to_owned(),
new_content,
)),
edit_json,
encryption_info: ctx.bundled_edit_encryption_info,
}),
);
self.aggregations.add(
TimelineEventItemId::EventId(ctx.event_id.to_owned()),
aggregation,
);
}
// Extract a potentially bundled edit.
if let Some((edit_event_id, new_content)) =
extract_poll_edit_content(ctx.relations)
{
let edit_json = extract_bundled_edit_event_json(ctx.raw_event);
let aggregation = Aggregation::new(
TimelineEventItemId::EventId(edit_event_id),
AggregationKind::Edit(PendingEdit {
kind: PendingEditKind::Poll(Replacement::new(
ctx.event_id.to_owned(),
new_content,
)),
edit_json,
encryption_info: ctx.bundled_edit_encryption_info,
}),
);
self.aggregations.add(
TimelineEventItemId::EventId(ctx.event_id.to_owned()),
aggregation,
);
}
self.mark_response(ctx.event_id, in_reply_to.as_ref());
@@ -415,28 +413,26 @@ impl TimelineMetadata {
// Record the bundled edit in the aggregations set, if any.
if let Some(ctx) = remote_ctx {
if let Some(new_content) = extract_room_msg_edit_content(ctx.relations) {
// It is replacing the current event.
if let Some(edit_event_id) =
ctx.raw_event.get_field::<OwnedEventId>("event_id").ok().flatten()
{
let edit_json = extract_bundled_edit_event_json(ctx.raw_event);
let aggregation = Aggregation::new(
TimelineEventItemId::EventId(edit_event_id),
AggregationKind::Edit(PendingEdit {
kind: PendingEditKind::RoomMessage(Replacement::new(
ctx.event_id.to_owned(),
new_content,
)),
edit_json,
encryption_info: ctx.bundled_edit_encryption_info,
}),
);
self.aggregations.add(
TimelineEventItemId::EventId(ctx.event_id.to_owned()),
aggregation,
);
}
// Extract a potentially bundled edit.
if let Some((edit_event_id, new_content)) =
extract_room_msg_edit_content(ctx.relations)
{
let edit_json = extract_bundled_edit_event_json(ctx.raw_event);
let aggregation = Aggregation::new(
TimelineEventItemId::EventId(edit_event_id),
AggregationKind::Edit(PendingEdit {
kind: PendingEditKind::RoomMessage(Replacement::new(
ctx.event_id.to_owned(),
new_content,
)),
edit_json,
encryption_info: ctx.bundled_edit_encryption_info,
}),
);
self.aggregations.add(
TimelineEventItemId::EventId(ctx.event_id.to_owned()),
aggregation,
);
}
self.mark_response(ctx.event_id, in_reply_to.as_ref());

View File

@@ -29,6 +29,7 @@ use ruma::{
},
html::RemoveReplyFallback,
serde::Raw,
OwnedEventId,
};
use tracing::{error, trace};
@@ -110,10 +111,10 @@ pub(crate) fn extract_bundled_edit_event_json(
}
/// Extracts a replacement for a room message, if present in the bundled
/// relations.
/// relations , along with the event ID of the replacement event.
pub(crate) fn extract_room_msg_edit_content(
relations: BundledMessageLikeRelations<AnySyncMessageLikeEvent>,
) -> Option<RoomMessageEventContentWithoutRelation> {
) -> Option<(OwnedEventId, RoomMessageEventContentWithoutRelation)> {
match *relations.replace? {
AnySyncMessageLikeEvent::RoomMessage(SyncRoomMessageEvent::Original(ev)) => match ev
.content
@@ -121,7 +122,7 @@ pub(crate) fn extract_room_msg_edit_content(
{
Some(Relation::Replacement(re)) => {
trace!("found a bundled edit event in a room message");
Some(re.new_content)
Some((ev.event_id, re.new_content))
}
_ => {
error!("got m.room.message event with an edit without a valid m.replace relation");
@@ -139,16 +140,16 @@ pub(crate) fn extract_room_msg_edit_content(
}
/// Extracts a replacement for a room message, if present in the bundled
/// relations.
/// relations, along with the event ID of the replacement event.
pub(crate) fn extract_poll_edit_content(
relations: BundledMessageLikeRelations<AnySyncMessageLikeEvent>,
) -> Option<NewUnstablePollStartEventContentWithoutRelation> {
) -> Option<(OwnedEventId, NewUnstablePollStartEventContentWithoutRelation)> {
match *relations.replace? {
AnySyncMessageLikeEvent::UnstablePollStart(SyncUnstablePollStartEvent::Original(ev)) => {
match ev.content {
UnstablePollStartEventContent::Replacement(re) => {
trace!("found a bundled edit event in a poll");
Some(re.relates_to.new_content)
Some((ev.event_id, re.relates_to.new_content))
}
_ => {
error!("got new poll start event in a bundled edit");