refactor: Handle Ephemerals method

This makes sure that the handle
ephemerals method becomes fully
type and null safe, does not handle
maps directly anymore and stores
the corresponding fake m.read
room account data only once
per sync.
This commit is contained in:
Christian Pauly 2022-06-29 14:41:50 +02:00
parent 248aba1199
commit 5b831fcc83
1 changed files with 46 additions and 27 deletions

View File

@ -1748,44 +1748,63 @@ class Client extends MatrixApi {
} }
Future<void> _handleEphemerals(Room room, List<BasicRoomEvent> events) async { Future<void> _handleEphemerals(Room room, List<BasicRoomEvent> events) async {
var updateReceipts = false;
final receiptStateContent =
room.roomAccountData['m.receipt']?.content ?? {};
for (final event in events) { for (final event in events) {
await _handleRoomEvents(room, [event], EventUpdateType.ephemeral); await _handleRoomEvents(room, [event], EventUpdateType.ephemeral);
// Receipt events are deltas between two states. We will create a // Receipt events are deltas between two states. We will create a
// fake room account data event for this and store the difference // fake room account data event for this and store the difference
// there. // there.
if (event.type == 'm.receipt') { if (event.type != 'm.receipt') continue;
final receiptStateContent = updateReceipts = true;
room.roomAccountData['m.receipt']?.content ?? {}; for (final entry in event.content.entries) {
for (final eventEntry in event.content.entries) { final eventId = entry.key;
final eventID = eventEntry.key; final value = entry.value;
if (event.content[eventID]['m.read'] != null) {
final Map<String, dynamic> userTimestampMap =
event.content[eventID]['m.read'];
for (final userTimestampMapEntry in userTimestampMap.entries) {
final mxid = userTimestampMapEntry.key;
// Remove previous receipt event from this user final userTimestampMap =
if (receiptStateContent[eventID] is Map<String, dynamic> && (value is Map ? Map<String, dynamic>.from(value) : null)
receiptStateContent[eventID]['m.read'] ?.tryGetMap<String, dynamic>('m.read');
is Map<String, dynamic> &&
receiptStateContent[eventID]['m.read'].containsKey(mxid)) { if (userTimestampMap == null) continue;
receiptStateContent[eventID]['m.read'].remove(mxid);
} for (final userTimestampMapEntry in userTimestampMap.entries) {
if (userTimestampMap[mxid] is Map<String, dynamic> && final mxid = userTimestampMapEntry.key;
userTimestampMap[mxid].containsKey('ts')) {
receiptStateContent[mxid] = { // Remove previous receipt event from this user
'event_id': eventID, if (receiptStateContent
'ts': userTimestampMap[mxid]['ts'], .tryGetMap<String, dynamic>(eventId)
}; ?.tryGetMap<String, dynamic>('m.read')
} ?.containsKey(mxid) ??
} false) {
receiptStateContent[eventId]['m.read'].remove(mxid);
}
if (userTimestampMap
.tryGetMap<String, dynamic>(mxid)
?.containsKey('ts') ??
false) {
receiptStateContent[mxid] = {
'event_id': eventId,
'ts': userTimestampMap[mxid]['ts'],
};
} }
} }
event.content = receiptStateContent;
await _handleRoomEvents(room, [event], EventUpdateType.accountData);
} }
} }
if (updateReceipts) {
await _handleRoomEvents(
room,
[
BasicRoomEvent(
type: 'm.receipt',
roomId: room.id,
content: receiptStateContent,
)
],
EventUpdateType.accountData);
}
} }
Future<void> _handleRoomEvents( Future<void> _handleRoomEvents(