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(