Skip to content

Commit

Permalink
refactor: support cached room state for archive
Browse files Browse the repository at this point in the history
- always try to get the timeline from database in Room.getTimeline
- only use Client.getArchiveRoomFromCache in case database has no events
- use Room.getTimeline in case the room is available while storing a
  room to archive

Signed-off-by: The one with the braid <[email protected]>
  • Loading branch information
TheOneWithTheBraid committed Oct 3, 2023
1 parent 78ab5ec commit 6ac677a
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 21 deletions.
48 changes: 34 additions & 14 deletions lib/src/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -934,40 +934,60 @@ class Client extends MatrixApi {
}

Future<void> _storeArchivedRoom(String id, LeftRoomUpdate update) async {
final room = update;
final leftRoom = Room(
id: id,
membership: Membership.leave,
client: this,
roomAccountData:
room.accountData?.asMap().map((k, v) => MapEntry(v.type, v)) ??
<String, BasicRoomEvent>{},
roomAccountData: update.accountData?.asMap().map(
(k, v) => MapEntry(v.type, v),
) ??
<String, BasicRoomEvent>{},
);

final timeline = Timeline(
final storedRoom = rooms.singleWhereOrNull((room) => room.id == id);

Timeline timeline;

// try to get the timeline from cache in case the [LeftRoomUpdate] was
// dropped in by a regular sync (aka room is about to be archived)
if (storedRoom != null) {
timeline = await storedRoom.getTimeline();
}
// otherwise build a new timeline from the provided chunk only
// (aka we were fetching the room archive in background)
else {
timeline = Timeline(
room: leftRoom,
chunk: TimelineChunk(
events: room.timeline?.events?.reversed
.toList() // we display the event in the other sence
.map((e) => Event.fromMatrixEvent(e, leftRoom))
.toList() ??
[]));

leftRoom.prev_batch = room.timeline?.prevBatch;
room.state?.forEach((event) {
events: update.timeline?.events?.reversed
.toList() // we display the event in the other sence
.map((e) => Event.fromMatrixEvent(e, leftRoom))
.toList() ??
[],
),
);
}

// in both cases add the events from the given chunk

leftRoom.prev_batch = update.timeline?.prevBatch;
update.state?.forEach((event) {
leftRoom.setState(Event.fromMatrixEvent(
event,
leftRoom,
));
});

room.timeline?.events?.forEach((event) {
update.timeline?.events?.forEach((event) {
leftRoom.setState(Event.fromMatrixEvent(
event,
leftRoom,
));
});

// TODO: it might be considerable to ditch this entire implementation
// in favor of archived rooms as regular rooms, could highly reduce
// code duplication, but that is not my cup of tea anymore
for (var i = 0; i < timeline.events.length; i++) {
// Try to decrypt encrypted events but don't update the database.
if (leftRoom.encrypted && leftRoom.client.encryptionEnabled) {
Expand Down
13 changes: 6 additions & 7 deletions lib/src/room.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1434,13 +1434,12 @@ class Room {

List<Event> events;

if (!isArchived) {
events = await client.database?.getEventList(
this,
limit: defaultHistoryCount,
) ??
<Event>[];
} else {
events = await client.database?.getEventList(
this,
limit: defaultHistoryCount,
) ??
<Event>[];
if (events.isEmpty && isArchived) {
final archive = client.getArchiveRoomFromCache(id);
events = archive?.timeline.events.toList() ?? [];
for (var i = 0; i < events.length; i++) {
Expand Down

0 comments on commit 6ac677a

Please sign in to comment.