getRoomList method
Implementation
@override
Future<List<Room>> getRoomList(Client client) =>
runBenchmarked<List<Room>>('Get room list from hive', () async {
final rooms = <String, Room>{};
final userID = client.userID;
final importantRoomStates = client.importantStateEvents;
for (final key in _roomsBox.keys) {
// Get the room
final raw = await _roomsBox.get(key);
final room = Room.fromJson(convertToJson(raw), client);
// let's see if we need any m.room.member events
// We always need the member event for ourself
final membersToPostload = <String>{if (userID != null) userID};
// If the room is a direct chat, those IDs should be there too
if (room.isDirectChat) {
membersToPostload.add(room.directChatSDNID!);
}
// the lastEvent message preview might have an author we need to fetch, if it is a group chat
final lastEvent = room.getState(EventTypes.Message);
if (lastEvent != null && !room.isDirectChat) {
membersToPostload.add(lastEvent.senderId);
}
// if the room has no name and no canonical alias, its name is calculated
// based on the heroes of the room
if (room.getState(EventTypes.RoomName) == null &&
room.getState(EventTypes.RoomCanonicalAlias) == null) {
// we don't have a name and no canonical alias, so we'll need to
// post-load the heroes
membersToPostload.addAll(room.summary.mHeroes ?? []);
}
// Load members
for (final userId in membersToPostload) {
final state =
await _roomMembersBox.get(MultiKey(room.id, userId).toString());
if (state == null) {
Logs().w('Unable to post load member $userId');
continue;
}
room.setState(Event.fromJson(convertToJson(state), room));
}
// Get the "important" room states. All other states will be loaded once
// `getUnimportantRoomStates()` is called.
for (final type in importantRoomStates) {
final states = await _roomStateBox
.get(MultiKey(room.id, type).toString()) as Map?;
if (states == null) continue;
final stateEvents = states.values
.map((raw) => Event.fromJson(convertToJson(raw), room))
.toList();
for (final state in stateEvents) {
room.setState(state);
}
}
// Add to the list and continue.
rooms[room.id] = room;
}
// Get the room account data
for (final key in _roomAccountDataBox.keys) {
final roomId = MultiKey.fromString(key).parts.first;
if (rooms.containsKey(roomId)) {
final raw = await _roomAccountDataBox.get(key);
final basicRoomEvent = BasicRoomEvent.fromJson(
convertToJson(raw),
);
rooms[roomId]!.roomAccountData[basicRoomEvent.type] =
basicRoomEvent;
} else {
Logs().w(
'Found account data for unknown room $roomId. Delete now...');
await _roomAccountDataBox.delete(key);
}
}
return rooms.values.toList();
}, _roomsBox.keys.length);