diff --git a/lib/src/room.dart b/lib/src/room.dart index 09425c30..affb06f3 100644 --- a/lib/src/room.dart +++ b/lib/src/room.dart @@ -1521,6 +1521,7 @@ class Room { void Function()? onNewEvent, void Function()? onUpdate, String? eventContextId, + int? limit = Room.defaultHistoryCount, }) async { await postLoad(); @@ -1529,7 +1530,7 @@ class Room { if (!isArchived) { events = await client.database?.getEventList( this, - limit: defaultHistoryCount, + limit: limit, ) ?? []; } else { diff --git a/lib/src/timeline.dart b/lib/src/timeline.dart index c0ddaa33..0d196c0e 100644 --- a/lib/src/timeline.dart +++ b/lib/src/timeline.dart @@ -152,6 +152,9 @@ class Timeline { ); if (eventsFromStore != null && eventsFromStore.isNotEmpty) { + for (final e in eventsFromStore) { + addAggregatedEvent(e); + } // Fetch all users from database we have got here. for (final event in events) { if (room.getState(EventTypes.RoomMember, event.senderId) != null) { @@ -500,12 +503,12 @@ class Timeline { if (relationshipType == null || relationshipEventId == null) { return; // nothing to do } - final events = (aggregatedEvents[relationshipEventId] ??= + final e = (aggregatedEvents[relationshipEventId] ??= >{})[relationshipType] ??= {}; // remove a potential old event - _removeEventFromSet(events, event); + _removeEventFromSet(e, event); // add the new one - events.add(event); + e.add(event); if (onChange != null) { final index = _findEvent(event_id: relationshipEventId); onChange?.call(index); @@ -518,8 +521,8 @@ class Timeline { aggregatedEvents.remove(event.transactionId); } for (final types in aggregatedEvents.values) { - for (final events in types.values) { - _removeEventFromSet(events, event); + for (final e in types.values) { + _removeEventFromSet(e, event); } } } diff --git a/pubspec.yaml b/pubspec.yaml index 776e12e5..9c5068bc 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -32,7 +32,7 @@ dependencies: sqflite_common: ^2.4.5 sqlite3: ^2.1.0 typed_data: ^1.3.2 - webrtc_interface: ^1.2.2+hotfix.1 + webrtc_interface: ^1.2.0 dev_dependencies: build_runner: ^2.4.15 diff --git a/test/timeline_test.dart b/test/timeline_test.dart index 32e0eceb..1bd989e8 100644 --- a/test/timeline_test.dart +++ b/test/timeline_test.dart @@ -1098,6 +1098,111 @@ void main() { expect(timeline.events[0].status, EventStatus.synced); expect(timeline.events.length, 1); }); + + test('make sure aggregated events are updated on requestHistory', () async { + timeline.events.clear(); + await client.handleSync( + SyncUpdate( + nextBatch: 'something', + rooms: RoomsUpdate( + join: { + timeline.room.id: JoinedRoomUpdate( + timeline: TimelineUpdate( + events: [ + MatrixEvent.fromJson({ + 'type': 'm.room.message', + 'content': {'msgtype': 'm.text', 'body': 'Testcase'}, + 'event_id': '11', + 'sender': '@alice:example.com', + 'origin_server_ts': DateTime.now().millisecondsSinceEpoch, + }), + MatrixEvent.fromJson({ + 'type': 'm.room.message', + 'content': {'msgtype': 'm.text', 'body': 'Testcase'}, + 'event_id': '22', + 'sender': '@alice:example.com', + 'origin_server_ts': DateTime.now().millisecondsSinceEpoch, + }), + MatrixEvent.fromJson({ + 'type': 'm.room.message', + 'content': { + 'msgtype': 'm.text', + 'body': '* edit 11', + 'm.new_content': { + 'msgtype': 'm.text', + 'body': 'edit 11', + 'm.mentions': {}, + }, + 'm.mentions': {}, + 'm.relates_to': { + 'rel_type': 'm.replace', + 'event_id': '11', + }, + }, + 'event_id': '33', + 'sender': '@alice:example.com', + 'origin_server_ts': DateTime.now().millisecondsSinceEpoch, + }), + MatrixEvent.fromJson({ + 'type': 'm.room.message', + 'content': { + 'msgtype': 'm.text', + 'body': '* edit 22', + 'm.new_content': { + 'msgtype': 'm.text', + 'body': 'edit 22', + 'm.mentions': {}, + }, + 'm.mentions': {}, + 'm.relates_to': { + 'rel_type': 'm.replace', + 'event_id': '22', + }, + }, + 'event_id': '44', + 'sender': '@alice:example.com', + 'origin_server_ts': DateTime.now().millisecondsSinceEpoch, + }), + ], + ), + ), + }, + ), + ), + ); + + final t = await room.getTimeline(limit: 1); + + expect(t.events.length, 1); + + expect( + t.events.single.getDisplayEvent(t).body, + '* edit 22', + ); + + await t.requestHistory(); + + expect( + t.events.reversed + .where( + (element) => element.relationshipType != RelationshipTypes.edit, + ) + .last + .getDisplayEvent(t) + .body, + 'edit 22', + ); + expect( + t.events.reversed + .where( + (element) => element.relationshipType != RelationshipTypes.edit, + ) + .first + .getDisplayEvent(t) + .body, + 'edit 11', + ); + }); test('logout', () async { await client.logout(); }); diff --git a/test/webrtc_stub.dart b/test/webrtc_stub.dart index 4eb55ac6..70516e92 100644 --- a/test/webrtc_stub.dart +++ b/test/webrtc_stub.dart @@ -849,8 +849,4 @@ class MockVideoRenderer implements VideoRenderer { // Mock implementation for disposing VideoRenderer Logs().i('Mock: Disposing VideoRenderer'); } - - @override - // TODO: implement videoValue - RTCVideoValue get videoValue => RTCVideoValue.empty; }