getRoomList method

  1. @override
Future<List<Room>> getRoomList(
  1. Client client
)
override

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.directChatMatrixID!);
        }
        // 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(room.membership == Membership.invite
              ? StrippedStateEvent.fromJson(copyMap(raw))
              : 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) => room.membership == Membership.invite
                  ? StrippedStateEvent.fromJson(copyMap(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);