feat: Support fallback for threads in Event.getReplyEvent()
This commit is contained in:
parent
aefd690125
commit
35b352e8c1
|
|
@ -481,13 +481,35 @@ class Event extends MatrixEvent {
|
||||||
Future<String?> redactEvent({String? reason, String? txid}) async =>
|
Future<String?> redactEvent({String? reason, String? txid}) async =>
|
||||||
await room.redactEvent(eventId, reason: reason, txid: txid);
|
await room.redactEvent(eventId, reason: reason, txid: txid);
|
||||||
|
|
||||||
/// Searches for the reply event in the given timeline.
|
/// Searches for the reply event in the given timeline. Also returns the
|
||||||
|
/// event fallback if the relationship type is `m.thread`.
|
||||||
|
/// https://spec.matrix.org/v1.14/client-server-api/#fallback-for-unthreaded-clients
|
||||||
Future<Event?> getReplyEvent(Timeline timeline) async {
|
Future<Event?> getReplyEvent(Timeline timeline) async {
|
||||||
if (relationshipType != RelationshipTypes.reply) return null;
|
switch (relationshipType) {
|
||||||
final relationshipEventId = this.relationshipEventId;
|
case RelationshipTypes.reply:
|
||||||
return relationshipEventId == null
|
final relationshipEventId = this.relationshipEventId;
|
||||||
? null
|
return relationshipEventId == null
|
||||||
: await timeline.getEventById(relationshipEventId);
|
? null
|
||||||
|
: await timeline.getEventById(relationshipEventId);
|
||||||
|
|
||||||
|
case RelationshipTypes.thread:
|
||||||
|
final relationshipContent =
|
||||||
|
content.tryGetMap<String, Object?>('m.relates_to');
|
||||||
|
if (relationshipContent == null) return null;
|
||||||
|
final String? relationshipEventId;
|
||||||
|
if (relationshipContent.tryGet<bool>('is_falling_back') == true) {
|
||||||
|
relationshipEventId = relationshipContent
|
||||||
|
.tryGetMap<String, Object?>('m.in_reply_to')
|
||||||
|
?.tryGet<String>('event_id');
|
||||||
|
} else {
|
||||||
|
relationshipEventId = this.relationshipEventId;
|
||||||
|
}
|
||||||
|
return relationshipEventId == null
|
||||||
|
? null
|
||||||
|
: await timeline.getEventById(relationshipEventId);
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If this event is encrypted and the decryption was not successful because
|
/// If this event is encrypted and the decryption was not successful because
|
||||||
|
|
|
||||||
|
|
@ -2862,5 +2862,49 @@ void main() {
|
||||||
matrixEvent.toJson(),
|
matrixEvent.toJson(),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('getReplyEvent fallback', () async {
|
||||||
|
final event = Event.fromJson(
|
||||||
|
{
|
||||||
|
'content': {
|
||||||
|
'msgtype': 'text',
|
||||||
|
'body': 'Hello world',
|
||||||
|
'm.relates_to': {
|
||||||
|
'rel_type': 'm.thread',
|
||||||
|
'event_id': '\$root',
|
||||||
|
'm.in_reply_to': {'event_id': '\$target'},
|
||||||
|
'is_falling_back': true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'event_id': '\$143273582443PhrSn:example.org',
|
||||||
|
'origin_server_ts': 1432735824653,
|
||||||
|
'room_id': room.id,
|
||||||
|
'sender': '@example:example.org',
|
||||||
|
'type': 'm.room.message',
|
||||||
|
'unsigned': {'age': 1234},
|
||||||
|
'redacts': 'abcd',
|
||||||
|
'prev_content': <String, Object?>{
|
||||||
|
'foo': 'bar',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
room,
|
||||||
|
);
|
||||||
|
expect(event.relationshipType, RelationshipTypes.thread);
|
||||||
|
expect(event.relationshipEventId, '\$root');
|
||||||
|
final targetEvent = Event(
|
||||||
|
eventId: '\$target',
|
||||||
|
senderId: '@example:example.org',
|
||||||
|
type: 'm.room.message',
|
||||||
|
content: {
|
||||||
|
'msgtype': 'text',
|
||||||
|
'body': 'Hello world',
|
||||||
|
},
|
||||||
|
originServerTs: DateTime.now(),
|
||||||
|
room: room,
|
||||||
|
);
|
||||||
|
final timeline =
|
||||||
|
Timeline(room: room, chunk: TimelineChunk(events: [targetEvent]));
|
||||||
|
expect(await event.getReplyEvent(timeline), targetEvent);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue