getRoomList method
Implementation
@override
Future<List<Room>> getRoomList(Client client) =>
runBenchmarked<List<Room>>('Get room list from store', () async {
final rooms = <String, Room>{};
final userID = client.userID;
final rawRooms = await _roomsBox.getAllValues();
final getRoomStateRequests = <String, Future<List>>{};
final getRoomMembersRequests = <String, Future<List>>{};
for (final raw in rawRooms.values) {
// Get the room
final room = Room.fromJson(copyMap(raw), client);
// Get the "important" room states. All other states will be loaded once
// `getUnimportantRoomStates()` is called.
final dbKeys = client.importantStateEvents
.map((state) => TupleKey(room.id, state).toString())
.toList();
getRoomStateRequests[room.id] = _roomStateBox.getAll(
dbKeys,
);
// Add to the list and continue.
rooms[room.id] = room;
}
for (final room in rooms.values) {
// Add states to the room
final statesList = await getRoomStateRequests[room.id];
if (statesList != null) {
for (final states in statesList) {
if (states == null) continue;
final stateEvents = states.values
.map((raw) => Event.fromJson(copyMap(raw), room))
.toList();
for (final state in stateEvents) {
room.setState(state);
}
}
// now that we have the state we can continue
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
if (room.lastEvent != null && !room.isDirectChat) {
membersToPostload.add(room.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
final heroes = room.summary.mHeroes;
if (heroes != null) {
heroes.forEach((hero) => membersToPostload.add(hero));
}
}
// Load members
final membersDbKeys = membersToPostload
.map((member) => TupleKey(room.id, member).toString())
.toList();
getRoomMembersRequests[room.id] = _roomMembersBox.getAll(
membersDbKeys,
);
}
}
for (final room in rooms.values) {
// Add members to the room
final members = await getRoomMembersRequests[room.id];
if (members != null) {
for (final member in members) {
if (member == null) continue;
room.setState(Event.fromJson(copyMap(member), room));
}
}
}
// Get the room account data
final roomAccountDataRaws = await _roomAccountDataBox.getAllValues();
for (final entry in roomAccountDataRaws.entries) {
final keys = TupleKey.fromString(entry.key);
final basicRoomEvent = BasicRoomEvent.fromJson(
copyMap(entry.value),
);
final roomId = keys.parts.first;
if (rooms.containsKey(roomId)) {
rooms[roomId]!.roomAccountData[basicRoomEvent.type] =
basicRoomEvent;
} else {
Logs().w(
'Found account data for unknown room $roomId. Delete now...');
await _roomAccountDataBox
.delete(TupleKey(roomId, basicRoomEvent.type).toString());
}
}
return rooms.values.toList();
});