getTimeline method
Creates a timeline from the store. Returns a Timeline object. If you
just want to update the whole timeline on every change, use the onUpdate
callback. For updating only the parts that have changed, use the
onChange
, onRemove
, onInsert
and the onHistoryReceived
callbacks.
This method can also retrieve the timeline at a specific point by setting
the eventContextId
Implementation
Future<Timeline> getTimeline(
{void Function(int index)? onChange,
void Function(int index)? onRemove,
void Function(int insertID)? onInsert,
void Function()? onNewEvent,
void Function()? onUpdate,
String? eventContextId}) async {
await postLoad();
List<Event> events;
if (!isArchived) {
events = await client.database?.getEventList(
this,
limit: defaultHistoryCount,
) ??
<Event>[];
} else {
final archive = client.getArchiveRoomFromCache(id);
events = archive?.timeline.events.toList() ?? [];
for (var i = 0; i < events.length; i++) {
// Try to decrypt encrypted events but don't update the database.
if (encrypted && client.encryptionEnabled) {
if (events[i].type == EventTypes.Encrypted) {
events[i] = await client.encryption!.decryptRoomEvent(
id,
events[i],
);
}
}
}
}
var chunk = TimelineChunk(events: events);
// Load the timeline arround eventContextId if set
if (eventContextId != null) {
if (!events.any((Event event) => event.eventId == eventContextId)) {
chunk =
await getEventContext(eventContextId) ?? TimelineChunk(events: []);
}
}
// Fetch all users from database we have got here.
if (eventContextId == null) {
for (final event in events) {
if (getState(EventTypes.RoomMember, event.senderId) != null) continue;
final dbUser = await client.database?.getUser(event.senderId, this);
if (dbUser != null) setState(dbUser);
}
}
// Try again to decrypt encrypted events and update the database.
if (encrypted && client.encryptionEnabled) {
// decrypt messages
for (var i = 0; i < chunk.events.length; i++) {
if (chunk.events[i].type == EventTypes.Encrypted) {
if (eventContextId != null) {
// for the fragmented timeline, we don't cache the decrypted
//message in the database
chunk.events[i] = await client.encryption!.decryptRoomEvent(
id,
chunk.events[i],
);
} else if (client.database != null) {
// else, we need the database
await client.database?.transaction(() async {
for (var i = 0; i < chunk.events.length; i++) {
if (chunk.events[i].content['can_request_session'] == true) {
chunk.events[i] = await client.encryption!.decryptRoomEvent(
id,
chunk.events[i],
store: !isArchived,
updateType: EventUpdateType.history,
);
}
}
});
}
}
}
}
final timeline = Timeline(
room: this,
chunk: chunk,
onChange: onChange,
onRemove: onRemove,
onInsert: onInsert,
onNewEvent: onNewEvent,
onUpdate: onUpdate);
return timeline;
}