Merge branch 'krille/timeline-auto-update-list' into 'main'
feat: Add onInsert, onRemove and onUpdate cb to timeline See merge request famedly/company/frontend/famedlysdk!880
This commit is contained in:
		
						commit
						7f9a75a43d
					
				|  | @ -35,7 +35,9 @@ class Timeline { | ||||||
|   final Map<String, Map<String, Set<Event>>> aggregatedEvents = {}; |   final Map<String, Map<String, Set<Event>>> aggregatedEvents = {}; | ||||||
| 
 | 
 | ||||||
|   final void Function()? onUpdate; |   final void Function()? onUpdate; | ||||||
|   final void Function(int insertID)? onInsert; |   final void Function(int index)? onChange; | ||||||
|  |   final void Function(int index)? onInsert; | ||||||
|  |   final void Function(int index)? onRemove; | ||||||
| 
 | 
 | ||||||
|   StreamSubscription<EventUpdate>? sub; |   StreamSubscription<EventUpdate>? sub; | ||||||
|   StreamSubscription<SyncUpdate>? roomSub; |   StreamSubscription<SyncUpdate>? roomSub; | ||||||
|  | @ -86,6 +88,11 @@ class Timeline { | ||||||
|       ); |       ); | ||||||
|       if (eventsFromStore != null && eventsFromStore.isNotEmpty) { |       if (eventsFromStore != null && eventsFromStore.isNotEmpty) { | ||||||
|         events.addAll(eventsFromStore); |         events.addAll(eventsFromStore); | ||||||
|  |         final startIndex = events.length - eventsFromStore.length; | ||||||
|  |         final endIndex = events.length; | ||||||
|  |         for (var i = startIndex; i < endIndex; i++) { | ||||||
|  |           onInsert?.call(i); | ||||||
|  |         } | ||||||
|       } else { |       } else { | ||||||
|         Logs().v('No more events found in the store. Request from server...'); |         Logs().v('No more events found in the store. Request from server...'); | ||||||
|         await room.requestHistory( |         await room.requestHistory( | ||||||
|  | @ -102,9 +109,14 @@ class Timeline { | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   Timeline( |   Timeline({ | ||||||
|       {required this.room, List<Event>? events, this.onUpdate, this.onInsert}) |     required this.room, | ||||||
|       : events = events ?? [] { |     List<Event>? events, | ||||||
|  |     this.onUpdate, | ||||||
|  |     this.onChange, | ||||||
|  |     this.onInsert, | ||||||
|  |     this.onRemove, | ||||||
|  |   }) : events = events ?? [] { | ||||||
|     sub = room.client.onEvent.stream.listen(_handleEventUpdate); |     sub = room.client.onEvent.stream.listen(_handleEventUpdate); | ||||||
|     // If the timeline is limited we want to clear our events cache |     // If the timeline is limited we want to clear our events cache | ||||||
|     roomSub = room.client.onSync.stream |     roomSub = room.client.onSync.stream | ||||||
|  | @ -142,6 +154,7 @@ class Timeline { | ||||||
|             events[i].content['session_id'] == sessionId) { |             events[i].content['session_id'] == sessionId) { | ||||||
|           events[i] = await encryption.decryptRoomEvent(room.id, events[i], |           events[i] = await encryption.decryptRoomEvent(room.id, events[i], | ||||||
|               store: true); |               store: true); | ||||||
|  |           onChange?.call(i); | ||||||
|           if (events[i].type != EventTypes.Encrypted) { |           if (events[i].type != EventTypes.Encrypted) { | ||||||
|             decryptAtLeastOneEvent = true; |             decryptAtLeastOneEvent = true; | ||||||
|           } |           } | ||||||
|  | @ -249,19 +262,21 @@ class Timeline { | ||||||
|           EventStatus.synced.intValue); |           EventStatus.synced.intValue); | ||||||
|       // Redaction events are handled as modification for existing events. |       // Redaction events are handled as modification for existing events. | ||||||
|       if (eventUpdate.content['type'] == EventTypes.Redaction) { |       if (eventUpdate.content['type'] == EventTypes.Redaction) { | ||||||
|         final eventId = _findEvent(event_id: eventUpdate.content['redacts']); |         final index = _findEvent(event_id: eventUpdate.content['redacts']); | ||||||
|         if (eventId < events.length) { |         if (index < events.length) { | ||||||
|           removeAggregatedEvent(events[eventId]); |           removeAggregatedEvent(events[index]); | ||||||
|           events[eventId].setRedactionEvent(Event.fromJson( |           events[index].setRedactionEvent(Event.fromJson( | ||||||
|             eventUpdate.content, |             eventUpdate.content, | ||||||
|             room, |             room, | ||||||
|           )); |           )); | ||||||
|  |           onChange?.call(index); | ||||||
|         } |         } | ||||||
|       } else if (status.isRemoved) { |       } else if (status.isRemoved) { | ||||||
|         final i = _findEvent(event_id: eventUpdate.content['event_id']); |         final i = _findEvent(event_id: eventUpdate.content['event_id']); | ||||||
|         if (i < events.length) { |         if (i < events.length) { | ||||||
|           removeAggregatedEvent(events[i]); |           removeAggregatedEvent(events[i]); | ||||||
|           events.removeAt(i); |           events.removeAt(i); | ||||||
|  |           onRemove?.call(i); | ||||||
|         } |         } | ||||||
|       } else { |       } else { | ||||||
|         final i = _findEvent( |         final i = _findEvent( | ||||||
|  | @ -283,6 +298,7 @@ class Timeline { | ||||||
|             events[i].status = oldStatus; |             events[i].status = oldStatus; | ||||||
|           } |           } | ||||||
|           addAggregatedEvent(events[i]); |           addAggregatedEvent(events[i]); | ||||||
|  |           onChange?.call(i); | ||||||
|         } else { |         } else { | ||||||
|           final newEvent = Event.fromJson( |           final newEvent = Event.fromJson( | ||||||
|             eventUpdate.content, |             eventUpdate.content, | ||||||
|  | @ -293,14 +309,16 @@ class Timeline { | ||||||
|               events.indexWhere( |               events.indexWhere( | ||||||
|                       (e) => e.eventId == eventUpdate.content['event_id']) != |                       (e) => e.eventId == eventUpdate.content['event_id']) != | ||||||
|                   -1) return; |                   -1) return; | ||||||
|  |           var index = events.length; | ||||||
|           if (eventUpdate.type == EventUpdateType.history) { |           if (eventUpdate.type == EventUpdateType.history) { | ||||||
|             events.add(newEvent); |             events.add(newEvent); | ||||||
|           } else { |           } else { | ||||||
|             events.insert(events.firstIndexWhereNotError, newEvent); |             index = events.firstIndexWhereNotError; | ||||||
|  |             events.insert(index, newEvent); | ||||||
|           } |           } | ||||||
| 
 | 
 | ||||||
|           addAggregatedEvent(newEvent); |           addAggregatedEvent(newEvent); | ||||||
|           onInsert?.call(0); |           onInsert?.call(index); | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|       if (update && !_collectHistoryUpdates) { |       if (update && !_collectHistoryUpdates) { | ||||||
|  |  | ||||||
|  | @ -34,6 +34,8 @@ void main() { | ||||||
|     final testTimeStamp = DateTime.now().millisecondsSinceEpoch; |     final testTimeStamp = DateTime.now().millisecondsSinceEpoch; | ||||||
|     var updateCount = 0; |     var updateCount = 0; | ||||||
|     final insertList = <int>[]; |     final insertList = <int>[]; | ||||||
|  |     final changeList = <int>[]; | ||||||
|  |     final removeList = <int>[]; | ||||||
|     var olmEnabled = true; |     var olmEnabled = true; | ||||||
| 
 | 
 | ||||||
|     late Client client; |     late Client client; | ||||||
|  | @ -59,9 +61,10 @@ void main() { | ||||||
|         onUpdate: () { |         onUpdate: () { | ||||||
|           updateCount++; |           updateCount++; | ||||||
|         }, |         }, | ||||||
|           onInsert: (int insertID) { |         onInsert: insertList.add, | ||||||
|             insertList.add(insertID); |         onChange: changeList.add, | ||||||
|           }); |         onRemove: removeList.add, | ||||||
|  |       ); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     test('Create', () async { |     test('Create', () async { | ||||||
|  | @ -100,6 +103,8 @@ void main() { | ||||||
|       expect(updateCount, 2); |       expect(updateCount, 2); | ||||||
|       expect(insertList, [0, 0]); |       expect(insertList, [0, 0]); | ||||||
|       expect(insertList.length, timeline.events.length); |       expect(insertList.length, timeline.events.length); | ||||||
|  |       expect(changeList, []); | ||||||
|  |       expect(removeList, []); | ||||||
|       expect(timeline.events.length, 2); |       expect(timeline.events.length, 2); | ||||||
|       expect(timeline.events[0].eventId, '1'); |       expect(timeline.events[0].eventId, '1'); | ||||||
|       expect(timeline.events[0].sender.id, '@alice:example.com'); |       expect(timeline.events[0].sender.id, '@alice:example.com'); | ||||||
|  | @ -146,6 +151,8 @@ void main() { | ||||||
|       expect(updateCount, 3); |       expect(updateCount, 3); | ||||||
|       expect(insertList, [0, 0]); |       expect(insertList, [0, 0]); | ||||||
|       expect(insertList.length, timeline.events.length); |       expect(insertList.length, timeline.events.length); | ||||||
|  |       expect(changeList, [1]); | ||||||
|  |       expect(removeList, []); | ||||||
|       expect(timeline.events.length, 2); |       expect(timeline.events.length, 2); | ||||||
|       expect(timeline.events[1].redacted, true); |       expect(timeline.events[1].redacted, true); | ||||||
|     }); |     }); | ||||||
|  | @ -211,8 +218,10 @@ void main() { | ||||||
|       await Future.delayed(Duration(milliseconds: 50)); |       await Future.delayed(Duration(milliseconds: 50)); | ||||||
| 
 | 
 | ||||||
|       expect(updateCount, 13); |       expect(updateCount, 13); | ||||||
|       expect(insertList, [0, 0, 0, 0, 0, 0, 0]); |       expect(insertList, [0, 0, 0, 0, 0, 1, 2]); | ||||||
|       expect(insertList.length, timeline.events.length); |       expect(insertList.length, timeline.events.length); | ||||||
|  |       expect(changeList, [1, 0, 0, 0, 1, 2]); | ||||||
|  |       expect(removeList, []); | ||||||
|       expect(timeline.events[0].status, EventStatus.error); |       expect(timeline.events[0].status, EventStatus.error); | ||||||
|       expect(timeline.events[1].status, EventStatus.error); |       expect(timeline.events[1].status, EventStatus.error); | ||||||
|       expect(timeline.events[2].status, EventStatus.error); |       expect(timeline.events[2].status, EventStatus.error); | ||||||
|  | @ -225,7 +234,9 @@ void main() { | ||||||
| 
 | 
 | ||||||
|       expect(updateCount, 14); |       expect(updateCount, 14); | ||||||
| 
 | 
 | ||||||
|       expect(insertList, [0, 0, 0, 0, 0, 0, 0]); |       expect(insertList, [0, 0, 0, 0, 0, 1, 2]); | ||||||
|  |       expect(changeList, [1, 0, 0, 0, 1, 2]); | ||||||
|  |       expect(removeList, [0]); | ||||||
|       expect(timeline.events.length, 6); |       expect(timeline.events.length, 6); | ||||||
|       expect(timeline.events[0].status, EventStatus.error); |       expect(timeline.events[0].status, EventStatus.error); | ||||||
|     }); |     }); | ||||||
|  | @ -270,7 +281,9 @@ void main() { | ||||||
| 
 | 
 | ||||||
|       expect(updateCount, 17); |       expect(updateCount, 17); | ||||||
| 
 | 
 | ||||||
|       expect(insertList, [0, 0, 0, 0, 0, 0, 0, 0]); |       expect(insertList, [0, 0, 0, 0, 0, 1, 2, 0]); | ||||||
|  |       expect(changeList, [1, 0, 0, 0, 1, 2, 0, 0]); | ||||||
|  |       expect(removeList, [0]); | ||||||
|       expect(timeline.events.length, 1); |       expect(timeline.events.length, 1); | ||||||
|       expect(timeline.events[0].status, EventStatus.sent); |       expect(timeline.events[0].status, EventStatus.sent); | ||||||
|     }); |     }); | ||||||
|  | @ -283,6 +296,7 @@ void main() { | ||||||
|       await Future.delayed(Duration(milliseconds: 50)); |       await Future.delayed(Duration(milliseconds: 50)); | ||||||
| 
 | 
 | ||||||
|       expect(updateCount, 20); |       expect(updateCount, 20); | ||||||
|  |       expect(insertList, [0, 0, 0, 0, 0, 1, 2, 0, 0, 1, 2]); | ||||||
|       expect(timeline.events.length, 3); |       expect(timeline.events.length, 3); | ||||||
|       expect(timeline.events[0].eventId, '3143273582443PhrSn:example.org'); |       expect(timeline.events[0].eventId, '3143273582443PhrSn:example.org'); | ||||||
|       expect(timeline.events[1].eventId, '2143273582443PhrSn:example.org'); |       expect(timeline.events[1].eventId, '2143273582443PhrSn:example.org'); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue