feat: Add Event.getDisplayEvent, which fetches an event based on all edits etc.

This commit is contained in:
Sorunome 2020-08-11 10:12:26 +02:00
parent c184dfba6b
commit 574fe27101
No known key found for this signature in database
GPG key ID: B19471D07FC9BE9C
2 changed files with 111 additions and 0 deletions

View file

@ -715,4 +715,28 @@ class Event extends MatrixEvent {
hasAggregatedEvents(timeline, type) hasAggregatedEvents(timeline, type)
? timeline.aggregatedEvents[eventId][type] ? timeline.aggregatedEvents[eventId][type]
: <Event>{}; : <Event>{};
/// Fetches the event to be rendered, taking into account all the edits and the like.
/// It needs a [timeline] for that.
Event getDisplayEvent(Timeline timeline) {
if (hasAggregatedEvents(timeline, RelationshipTypes.Edit)) {
// alright, we have an edit
final allEditEvents = aggregatedEvents(timeline, RelationshipTypes.Edit)
// we only allow edits made by the original author themself
.where((e) => e.senderId == senderId && e.type == EventTypes.Message)
.toList();
// we need to check again if it isn't empty, as we potentially removed all
// aggregated edits
if (allEditEvents.isNotEmpty) {
allEditEvents.sort((a, b) => a.sortOrder - b.sortOrder > 0 ? 1 : -1);
var rawEvent = allEditEvents.last.toJson();
// update the content of the new event to render
if (rawEvent['content']['m.new_content'] is Map) {
rawEvent['content'] = rawEvent['content']['m.new_content'];
}
return Event.fromJson(rawEvent, room);
}
}
return this;
}
} }

View file

@ -873,5 +873,92 @@ void main() {
expect( expect(
event.aggregatedEvents(timeline, RelationshipTypes.Edit), <Event>{}); event.aggregatedEvents(timeline, RelationshipTypes.Edit), <Event>{});
}); });
test('getDisplayEvent', () {
var event = Event.fromJson({
'type': EventTypes.Message,
'content': {
'body': 'blah',
'msgtype': 'm.text',
},
'event_id': '\$source',
'sender': '@alice:example.org',
}, null);
event.sortOrder = 0;
var edit1 = Event.fromJson({
'type': EventTypes.Message,
'content': {
'body': '* edit 1',
'msgtype': 'm.text',
'm.new_content': {
'body': 'edit 1',
'msgtype': 'm.text',
},
'm.relates_to': {
'event_id': '\$source',
'rel_type': RelationshipTypes.Edit,
},
},
'event_id': '\$edit1',
'sender': '@alice:example.org',
}, null);
edit1.sortOrder = 1;
var edit2 = Event.fromJson({
'type': EventTypes.Message,
'content': {
'body': '* edit 2',
'msgtype': 'm.text',
'm.new_content': {
'body': 'edit 2',
'msgtype': 'm.text',
},
'm.relates_to': {
'event_id': '\$source',
'rel_type': RelationshipTypes.Edit,
},
},
'event_id': '\$edit2',
'sender': '@alice:example.org',
}, null);
edit2.sortOrder = 2;
var edit3 = Event.fromJson({
'type': EventTypes.Message,
'content': {
'body': '* edit 3',
'msgtype': 'm.text',
'm.new_content': {
'body': 'edit 3',
'msgtype': 'm.text',
},
'm.relates_to': {
'event_id': '\$source',
'rel_type': RelationshipTypes.Edit,
},
},
'event_id': '\$edit3',
'sender': '@bob:example.org',
}, null);
edit3.sortOrder = 3;
var room = Room(client: client);
// no edits
var displayEvent =
event.getDisplayEvent(Timeline(events: <Event>[event], room: room));
expect(displayEvent.body, 'blah');
// one edit
displayEvent = event
.getDisplayEvent(Timeline(events: <Event>[event, edit1], room: room));
expect(displayEvent.body, 'edit 1');
// two edits
displayEvent = event.getDisplayEvent(
Timeline(events: <Event>[event, edit1, edit2], room: room));
expect(displayEvent.body, 'edit 2');
// foreign edit
displayEvent = event
.getDisplayEvent(Timeline(events: <Event>[event, edit3], room: room));
expect(displayEvent.body, 'blah');
// mixed foreign and non-foreign
displayEvent = event.getDisplayEvent(
Timeline(events: <Event>[event, edit1, edit2, edit3], room: room));
expect(displayEvent.body, 'edit 2');
});
}); });
} }