From 5b831fcc83135096df8085b707ca5b7fe3b668ba Mon Sep 17 00:00:00 2001 From: Christian Pauly Date: Wed, 29 Jun 2022 14:41:50 +0200 Subject: [PATCH] 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. --- lib/src/client.dart | 73 ++++++++++++++++++++++++++++----------------- 1 file changed, 46 insertions(+), 27 deletions(-) diff --git a/lib/src/client.dart b/lib/src/client.dart index def88969..d8def7c9 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -1748,44 +1748,63 @@ class Client extends MatrixApi { } Future _handleEphemerals(Room room, List events) async { + var updateReceipts = false; + final receiptStateContent = + room.roomAccountData['m.receipt']?.content ?? {}; for (final event in events) { await _handleRoomEvents(room, [event], EventUpdateType.ephemeral); // Receipt events are deltas between two states. We will create a // fake room account data event for this and store the difference // there. - if (event.type == 'm.receipt') { - final receiptStateContent = - room.roomAccountData['m.receipt']?.content ?? {}; - for (final eventEntry in event.content.entries) { - final eventID = eventEntry.key; - if (event.content[eventID]['m.read'] != null) { - final Map userTimestampMap = - event.content[eventID]['m.read']; - for (final userTimestampMapEntry in userTimestampMap.entries) { - final mxid = userTimestampMapEntry.key; + if (event.type != 'm.receipt') continue; + updateReceipts = true; + for (final entry in event.content.entries) { + final eventId = entry.key; + final value = entry.value; - // Remove previous receipt event from this user - if (receiptStateContent[eventID] is Map && - receiptStateContent[eventID]['m.read'] - is Map && - receiptStateContent[eventID]['m.read'].containsKey(mxid)) { - receiptStateContent[eventID]['m.read'].remove(mxid); - } - if (userTimestampMap[mxid] is Map && - userTimestampMap[mxid].containsKey('ts')) { - receiptStateContent[mxid] = { - 'event_id': eventID, - 'ts': userTimestampMap[mxid]['ts'], - }; - } - } + final userTimestampMap = + (value is Map ? Map.from(value) : null) + ?.tryGetMap('m.read'); + + if (userTimestampMap == null) continue; + + for (final userTimestampMapEntry in userTimestampMap.entries) { + final mxid = userTimestampMapEntry.key; + + // Remove previous receipt event from this user + if (receiptStateContent + .tryGetMap(eventId) + ?.tryGetMap('m.read') + ?.containsKey(mxid) ?? + false) { + receiptStateContent[eventId]['m.read'].remove(mxid); + } + if (userTimestampMap + .tryGetMap(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 _handleRoomEvents(