Merge branch 'td/fixParsing' into 'main'
chore: fix edited last events breaking db See merge request famedly/company/frontend/famedlysdk!1309
This commit is contained in:
commit
bd4ae6d747
|
|
@ -990,6 +990,7 @@ class HiveCollectionsDatabase extends DatabaseApi {
|
|||
Future<void> storeEventUpdate(EventUpdate eventUpdate, Client client) async {
|
||||
// Ephemerals should not be stored
|
||||
if (eventUpdate.type == EventUpdateType.ephemeral) return;
|
||||
|
||||
final tmpRoom = client.getRoomById(eventUpdate.roomID) ??
|
||||
Room(id: eventUpdate.roomID, client: client);
|
||||
|
||||
|
|
@ -1107,13 +1108,17 @@ class HiveCollectionsDatabase extends DatabaseApi {
|
|||
await removeEvent(transactionId, eventUpdate.roomID);
|
||||
}
|
||||
}
|
||||
|
||||
final stateKey =
|
||||
client.roomPreviewLastEvents.contains(eventUpdate.content['type'])
|
||||
? ''
|
||||
: eventUpdate.content['state_key'];
|
||||
// Store a common state event
|
||||
if ({
|
||||
EventUpdateType.timeline,
|
||||
EventUpdateType.state,
|
||||
EventUpdateType.inviteState
|
||||
}.contains(eventUpdate.type)) {
|
||||
EventUpdateType.timeline,
|
||||
EventUpdateType.state,
|
||||
EventUpdateType.inviteState
|
||||
}.contains(eventUpdate.type) &&
|
||||
stateKey != null) {
|
||||
if (eventUpdate.content['type'] == EventTypes.RoomMember) {
|
||||
await _roomMembersBox.put(
|
||||
TupleKey(
|
||||
|
|
@ -1133,29 +1138,36 @@ class HiveCollectionsDatabase extends DatabaseApi {
|
|||
.tryGetMap<String, dynamic>('content')
|
||||
?.tryGetMap<String, dynamic>('m.relates_to') ==
|
||||
null) {
|
||||
stateMap[eventUpdate.content['state_key'] ?? ''] =
|
||||
eventUpdate.content;
|
||||
stateMap[stateKey] = eventUpdate.content;
|
||||
await _roomStateBox.put(key, stateMap);
|
||||
} else {
|
||||
final editedEventRelationshipEventId = eventUpdate.content
|
||||
.tryGetMap<String, dynamic>('content')
|
||||
?.tryGetMap<String, dynamic>('m.relates_to')
|
||||
?.tryGet<String>('event_id');
|
||||
final state = stateMap[''] == null
|
||||
? null
|
||||
: Event.fromJson(stateMap[''] as Map<String, dynamic>, tmpRoom);
|
||||
if (eventUpdate.content['type'] != EventTypes.Message ||
|
||||
eventUpdate.content
|
||||
.tryGetMap<String, dynamic>('content')
|
||||
?.tryGetMap<String, dynamic>('m.relates_to')
|
||||
?.tryGet<String>('rel_type') !=
|
||||
RelationshipTypes.edit ||
|
||||
editedEventRelationshipEventId == state?.eventId ||
|
||||
((state?.relationshipType == RelationshipTypes.edit &&
|
||||
|
||||
final tmpRoom = client.getRoomById(eventUpdate.roomID) ??
|
||||
Room(id: eventUpdate.roomID, client: client);
|
||||
|
||||
if (eventUpdate.content['type'] !=
|
||||
EventTypes
|
||||
.Message || // send anything other than a message
|
||||
eventUpdate.content
|
||||
.tryGetMap<String, dynamic>('content')
|
||||
?.tryGetMap<String, dynamic>('m.relates_to')
|
||||
?.tryGet<String>('rel_type') !=
|
||||
RelationshipTypes
|
||||
.edit || // replies are always latest anyway
|
||||
editedEventRelationshipEventId ==
|
||||
state?.relationshipEventId))) {
|
||||
stateMap[eventUpdate.content['state_key'] ?? ''] =
|
||||
eventUpdate.content;
|
||||
tmpRoom.lastEvent
|
||||
?.eventId || // edit of latest (original event) event
|
||||
(tmpRoom.lastEvent?.relationshipType ==
|
||||
RelationshipTypes.edit &&
|
||||
editedEventRelationshipEventId ==
|
||||
tmpRoom.lastEvent
|
||||
?.relationshipEventId) // edit of latest (edited event) event
|
||||
) {
|
||||
stateMap[stateKey] = eventUpdate.content;
|
||||
await _roomStateBox.put(key, stateMap);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1049,12 +1049,17 @@ class FamedlySdkHiveDatabase extends DatabaseApi {
|
|||
}
|
||||
}
|
||||
|
||||
final stateKey =
|
||||
client.roomPreviewLastEvents.contains(eventUpdate.content['type'])
|
||||
? ''
|
||||
: eventUpdate.content['state_key'];
|
||||
// Store a common state event
|
||||
if ({
|
||||
EventUpdateType.timeline,
|
||||
EventUpdateType.state,
|
||||
EventUpdateType.inviteState
|
||||
}.contains(eventUpdate.type)) {
|
||||
EventUpdateType.timeline,
|
||||
EventUpdateType.state,
|
||||
EventUpdateType.inviteState
|
||||
}.contains(eventUpdate.type) &&
|
||||
stateKey != null) {
|
||||
if (eventUpdate.content['type'] == EventTypes.RoomMember) {
|
||||
await _roomMembersBox.put(
|
||||
MultiKey(
|
||||
|
|
@ -1068,30 +1073,43 @@ class FamedlySdkHiveDatabase extends DatabaseApi {
|
|||
eventUpdate.content['type'],
|
||||
).toString();
|
||||
final Map stateMap = await _roomStateBox.get(key) ?? {};
|
||||
|
||||
// store state events and new messages, that either are not an edit or an edit of the lastest message
|
||||
// An edit is an event, that has an edit relation to the latest event. In some cases for the second edit, we need to compare if both have an edit relation to the same event instead.
|
||||
if (eventUpdate.content
|
||||
.tryGetMap<String, dynamic>('content')
|
||||
?.tryGetMap<String, dynamic>('m.relates_to') ==
|
||||
null) {
|
||||
stateMap[eventUpdate.content['state_key']] = eventUpdate.content;
|
||||
stateMap[stateKey] = eventUpdate.content;
|
||||
await _roomStateBox.put(key, stateMap);
|
||||
} else {
|
||||
final editedEventRelationshipEventId = eventUpdate.content
|
||||
.tryGetMap<String, dynamic>('content')
|
||||
?.tryGetMap<String, dynamic>('m.relates_to')
|
||||
?.tryGet<String>('event_id');
|
||||
if (eventUpdate.content['type'] != EventTypes.Message ||
|
||||
eventUpdate.content
|
||||
.tryGetMap<String, dynamic>('content')
|
||||
?.tryGetMap<String, dynamic>('m.relates_to')
|
||||
?.tryGet<String>('rel_type') !=
|
||||
RelationshipTypes.edit ||
|
||||
editedEventRelationshipEventId == stateMap['']?.eventId ||
|
||||
((stateMap['']?.relationshipType == RelationshipTypes.edit &&
|
||||
|
||||
final tmpRoom = client.getRoomById(eventUpdate.roomID) ??
|
||||
Room(id: eventUpdate.roomID, client: client);
|
||||
|
||||
if (eventUpdate.content['type'] !=
|
||||
EventTypes
|
||||
.Message || // send anything other than a message
|
||||
eventUpdate.content
|
||||
.tryGetMap<String, dynamic>('content')
|
||||
?.tryGetMap<String, dynamic>('m.relates_to')
|
||||
?.tryGet<String>('rel_type') !=
|
||||
RelationshipTypes
|
||||
.edit || // replies are always latest anyway
|
||||
editedEventRelationshipEventId ==
|
||||
stateMap['']?.relationshipEventId))) {
|
||||
stateMap[eventUpdate.content['state_key']] = eventUpdate.content;
|
||||
tmpRoom.lastEvent
|
||||
?.eventId || // edit of latest (original event) event
|
||||
(tmpRoom.lastEvent?.relationshipType ==
|
||||
RelationshipTypes.edit &&
|
||||
editedEventRelationshipEventId ==
|
||||
tmpRoom.lastEvent
|
||||
?.relationshipEventId) // edit of latest (edited event) event
|
||||
) {
|
||||
stateMap[stateKey] = eventUpdate.content;
|
||||
await _roomStateBox.put(key, stateMap);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,5 +37,4 @@ dev_dependencies:
|
|||
import_sorter: ^4.6.0
|
||||
lints: ^2.0.0
|
||||
test: ^1.15.7
|
||||
test_api: 0.4.16 # pinned because of https://github.com/dart-lang/test/issues/1977
|
||||
#flutter_test: {sdk: flutter}
|
||||
|
|
|
|||
|
|
@ -332,6 +332,99 @@ void main() {
|
|||
);
|
||||
expect(room.lastEvent?.body, 'B');
|
||||
});
|
||||
|
||||
test('lastEvent with deleted message', () async {
|
||||
room.setState(
|
||||
Event(
|
||||
senderId: '@test:example.com',
|
||||
type: 'm.room.encrypted',
|
||||
room: room,
|
||||
eventId: '8',
|
||||
originServerTs: DateTime.now(),
|
||||
content: {'msgtype': 'm.text', 'body': 'AA'},
|
||||
stateKey: '',
|
||||
),
|
||||
);
|
||||
expect(room.lastEvent?.body, 'AA');
|
||||
|
||||
room.setState(
|
||||
Event(
|
||||
senderId: '@test:example.com',
|
||||
type: 'm.room.encrypted',
|
||||
room: room,
|
||||
eventId: '9',
|
||||
originServerTs: DateTime.now(),
|
||||
content: {
|
||||
'msgtype': 'm.text',
|
||||
'body': 'B',
|
||||
'm.relates_to': {'rel_type': 'm.in_reply_to', 'event_id': '8'}
|
||||
},
|
||||
stateKey: '',
|
||||
),
|
||||
);
|
||||
expect(room.lastEvent?.body, 'B');
|
||||
|
||||
room.setState(
|
||||
Event(
|
||||
senderId: '@test:example.com',
|
||||
type: 'm.room.encrypted',
|
||||
room: room,
|
||||
eventId: '10',
|
||||
originServerTs: DateTime.now(),
|
||||
content: {
|
||||
'type': 'm.room.redaction',
|
||||
'content': {'reason': 'test'},
|
||||
'sender': '@test:example.com',
|
||||
'redacts': '9',
|
||||
'event_id': '10',
|
||||
'origin_server_ts': DateTime.now(),
|
||||
},
|
||||
stateKey: '',
|
||||
),
|
||||
);
|
||||
expect(room.lastEvent?.eventId, '10');
|
||||
room.setState(
|
||||
Event(
|
||||
senderId: '@test:example.com',
|
||||
type: 'm.room.encrypted',
|
||||
room: room,
|
||||
eventId: '11',
|
||||
originServerTs: DateTime.now(),
|
||||
content: {'msgtype': 'm.text', 'body': 'BB'},
|
||||
stateKey: '',
|
||||
),
|
||||
);
|
||||
expect(room.lastEvent?.body, 'BB');
|
||||
room.setState(
|
||||
Event(
|
||||
senderId: '@test:example.com',
|
||||
type: 'm.room.encrypted',
|
||||
room: room,
|
||||
eventId: '12',
|
||||
originServerTs: DateTime.now(),
|
||||
content: {
|
||||
'm.new_content': {'msgtype': 'm.text', 'body': 'BBB'},
|
||||
'm.relates_to': {'rel_type': 'm.replace', 'event_id': '11'},
|
||||
'msgtype': 'm.text',
|
||||
'body': '* BBB',
|
||||
},
|
||||
stateKey: '',
|
||||
),
|
||||
);
|
||||
expect(room.lastEvent?.body, '* BBB');
|
||||
room.setState(
|
||||
Event(
|
||||
senderId: '@test:example.com',
|
||||
type: 'm.room.name',
|
||||
room: room,
|
||||
eventId: '12',
|
||||
originServerTs: DateTime.now(),
|
||||
content: {'body': 'brainfarts'},
|
||||
),
|
||||
);
|
||||
expect(room.lastEvent?.body, '* BBB');
|
||||
});
|
||||
|
||||
test('sendReadMarker', () async {
|
||||
await room.setReadMarker('§1234:fakeServer.notExisting');
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue