Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 31 additions & 50 deletions lib/src/event.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import 'package:matrix/src/utils/markdown.dart';
import 'package:matrix/src/utils/multipart_request_progress.dart';

abstract class RelationshipTypes {
static const String reply = 'm.in_reply_to';
static const String edit = 'm.replace';
static const String reaction = 'm.annotation';
static const String reference = 'm.reference';
Expand Down Expand Up @@ -490,31 +489,13 @@ class Event extends MatrixEvent {
/// 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 {
switch (relationshipType) {
case RelationshipTypes.reply:
final relationshipEventId = this.relationshipEventId;
return relationshipEventId == null
? 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;
}
final relationshipEventId = content
.tryGetMap<String, Object?>('m.relates_to')
?.tryGetMap<String, Object?>('m.in_reply_to')
?.tryGet<String>('event_id');
return relationshipEventId == null
? null
: await timeline.getEventById(relationshipEventId);
}

/// If this event is encrypted and the decryption was not successful because
Expand Down Expand Up @@ -1021,30 +1002,30 @@ class Event extends MatrixEvent {
return transactionId == search;
}

/// Get the relationship type of an event. `null` if there is none
String? get relationshipType {
final mRelatesTo = content.tryGetMap<String, Object?>('m.relates_to');
if (mRelatesTo == null) {
return null;
}
final relType = mRelatesTo.tryGet<String>('rel_type');
if (relType == RelationshipTypes.thread) {
return RelationshipTypes.thread;
}

if (mRelatesTo.containsKey('m.in_reply_to')) {
return RelationshipTypes.reply;
}
return relType;
}

/// Get the event ID that this relationship will reference. `null` if there is none
String? get relationshipEventId {
final relatesToMap = content.tryGetMap<String, Object?>('m.relates_to');
return relatesToMap?.tryGet<String>('event_id') ??
relatesToMap
?.tryGetMap<String, Object?>('m.in_reply_to')
?.tryGet<String>('event_id');
/// Get the relationship type of an event. `null` if there is none.
String? get relationshipType => content
.tryGetMap<String, Object?>('m.relates_to')
?.tryGet<String>('rel_type');

/// Get the event ID that this relationship will reference and `null` if there
/// is none. This could for example be the thread root, the original event for
/// an edit or the event, this is an reaction for. For replies please use
/// `Event.inReplyToEventId()` instead!
String? get relationshipEventId => content
.tryGetMap<String, Object?>('m.relates_to')
?.tryGet<String>('event_id');

/// If this event is in reply to another event, this returns the event ID or
/// null if this event is not a reply.
String? inReplyToEventId({bool includingFallback = true}) {
final isFallback = content
.tryGetMap<String, Object?>('m.relates_to')
?.tryGet<bool>('is_falling_back');
if (isFallback == true && !includingFallback) return null;
return content
.tryGetMap<String, Object?>('m.relates_to')
?.tryGetMap<String, Object?>('m.in_reply_to')
?.tryGet<String>('event_id');
}

/// Get whether this event has aggregated events from a certain [type]
Expand Down
24 changes: 19 additions & 5 deletions test/event_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ void main() async {
expect(event.formattedText, formatted_body);
expect(event.body, body);
expect(event.type, EventTypes.Message);
expect(event.relationshipType, RelationshipTypes.reply);
expect(event.inReplyToEventId(), '\$1234:example.com');
jsonObj['state_key'] = '';
final state = Event.fromJson(jsonObj, room);
expect(state.eventId, id);
Expand Down Expand Up @@ -178,8 +178,8 @@ void main() async {
};
event = Event.fromJson(jsonObj, room);
expect(event.messageType, MessageTypes.Text);
expect(event.relationshipType, RelationshipTypes.reply);
expect(event.relationshipEventId, '1234');
expect(event.inReplyToEventId(), '1234');
expect(event.relationshipEventId, null);
});

test('relationship types', () async {
Expand Down Expand Up @@ -212,8 +212,22 @@ void main() async {
},
};
event = Event.fromJson(jsonObj, room);
expect(event.relationshipType, RelationshipTypes.reply);
expect(event.relationshipEventId, 'def');
expect(event.inReplyToEventId(), 'def');
expect(event.relationshipEventId, null);

jsonObj['content']['m.relates_to'] = {
'rel_type': 'm.thread',
'event_id': '\$root',
'm.in_reply_to': {
'event_id': '\$target',
},
'is_falling_back': true,
};
event = Event.fromJson(jsonObj, room);
expect(event.relationshipType, RelationshipTypes.thread);
expect(event.inReplyToEventId(), '\$target');
expect(event.inReplyToEventId(includingFallback: false), null);
expect(event.relationshipEventId, '\$root');
});

test('redact', () async {
Expand Down
Loading