Skip to content
Snippets Groups Projects
RoomDirectoryModel.cpp 6.2 KiB
Newer Older
  • Learn to ignore specific revisions
  • // SPDX-FileCopyrightText: 2021 Nheko Contributors
    //
    // SPDX-License-Identifier: GPL-3.0-or-later
    
    #include "RoomDirectoryModel.h"
    
    #include "Cache.h"
    
    kamathmanu's avatar
    kamathmanu committed
    #include "ChatPage.h"
    
    
    #include <algorithm>
    
    RoomDirectoryModel::RoomDirectoryModel(QObject *parent, const std::string &s)
    
    kamathmanu's avatar
    kamathmanu committed
      : QAbstractListModel(parent)
      , server_(s)
    
    kamathmanu's avatar
    kamathmanu committed
            connect(this,
                    &RoomDirectoryModel::fetchedRoomsBatch,
                    this,
                    &RoomDirectoryModel::displayRooms,
                    Qt::QueuedConnection);
    
    kamathmanu's avatar
    kamathmanu committed
    QHash<int, QByteArray>
    
    kamathmanu's avatar
    kamathmanu committed
            return {
              {Roles::Name, "name"},
              {Roles::Id, "roomid"},
              {Roles::AvatarUrl, "avatarUrl"},
              {Roles::Topic, "topic"},
              {Roles::MemberCount, "numMembers"},
              {Roles::Previewable, "canPreview"},
            };
    
    kamathmanu's avatar
    kamathmanu committed
            beginResetModel();
    
    kamathmanu's avatar
    kamathmanu committed
            prevBatch_    = "";
            nextBatch_    = "";
            canFetchMore_ = true;
    
    kamathmanu's avatar
    kamathmanu committed
            publicRoomsData_.clear();
    
    kamathmanu's avatar
    kamathmanu committed
            endResetModel();
    
    kamathmanu's avatar
    kamathmanu committed
            server_ = s.toStdString();
    
    kamathmanu's avatar
    kamathmanu committed
            nhlog::ui()->debug("Received matrix server: {}", server_);
    
    kamathmanu's avatar
    kamathmanu committed
            resetDisplayedData();
    
    kamathmanu's avatar
    kamathmanu committed
            userSearchString_ = f.toStdString();
    
    kamathmanu's avatar
    kamathmanu committed
            nhlog::ui()->debug("Received user query: {}", userSearchString_);
    
    kamathmanu's avatar
    kamathmanu committed
            resetDisplayedData();
    
    bool
    RoomDirectoryModel::canJoinRoom(const QByteArray &room)
    {
    
    kamathmanu's avatar
    kamathmanu committed
            const auto &cache = cache::roomInfo();
            const QString room_id(room);
            const bool validRoom = !room_id.isNull() && !room_id.isEmpty();
            return validRoom && !cache.contains(room_id);
    
    std::vector<std::string>
    RoomDirectoryModel::getViasForRoom(const std::vector<std::string> &aliases)
    {
    
    kamathmanu's avatar
    kamathmanu committed
            std::vector<std::string> vias;
    
    kamathmanu's avatar
    kamathmanu committed
            vias.reserve(aliases.size());
    
    kamathmanu's avatar
    kamathmanu committed
            std::transform(
              aliases.begin(), aliases.end(), std::back_inserter(vias), [](const auto &alias) {
    
    kamathmanu's avatar
    kamathmanu committed
                      return alias.substr(alias.find(":") + 1);
    
    kamathmanu's avatar
    kamathmanu committed
              });
    
            return vias;
    
    kamathmanu's avatar
    kamathmanu committed
            if (index >= 0 && static_cast<size_t>(index) < publicRoomsData_.size()) {
                    const auto &chunk = publicRoomsData_[index];
                    nhlog::ui()->debug("'Joining room {}", chunk.room_id);
                    ChatPage::instance()->joinRoomVia(chunk.room_id, getViasForRoom(chunk.aliases));
            }
    
    }
    
    QVariant
    RoomDirectoryModel::data(const QModelIndex &index, int role) const
    {
    
    kamathmanu's avatar
    kamathmanu committed
            if (hasIndex(index.row(), index.column(), index.parent())) {
                    const auto &room_chunk = publicRoomsData_[index.row()];
                    switch (role) {
                    case Roles::Name:
                            return QString::fromStdString(room_chunk.name);
                    case Roles::Id:
                            return QString::fromStdString(room_chunk.room_id);
                    case Roles::AvatarUrl:
                            return QString::fromStdString(room_chunk.avatar_url);
                    case Roles::Topic:
                            return QString::fromStdString(room_chunk.topic);
                    case Roles::MemberCount:
                            return QVariant::fromValue(room_chunk.num_joined_members);
                    case Roles::Previewable:
                            return QVariant::fromValue(room_chunk.world_readable);
                    }
    
    kamathmanu's avatar
    kamathmanu committed
            return {};
    
    kamathmanu's avatar
    kamathmanu committed
    RoomDirectoryModel::fetchMore(const QModelIndex &)
    
    	if (!canFetchMore_) return;	
    
    
    kamathmanu's avatar
    kamathmanu committed
            nhlog::net()->debug("Fetching more rooms from mtxclient...");
    
            mtx::requests::PublicRooms req;
            req.limit                      = limit_;
            req.since                      = prevBatch_;
            req.filter.generic_search_term = userSearchString_;
            // req.third_party_instance_id = third_party_instance_id;
            auto requested_server = server_;
    
    
    	reachedEndOfPagination_ = false;
    	emit reachedEndOfPaginationChanged();
    
    	loadingMoreRooms_ = true;
    	emit loadingMoreRoomsChanged();
    
    
    kamathmanu's avatar
    kamathmanu committed
            http::client()->post_public_rooms(
              req,
              [requested_server, this, req](const mtx::responses::PublicRooms &res,
                                            mtx::http::RequestErr err) {
    
    		  loadingMoreRooms_ = false;
    		  emit loadingMoreRoomsChanged();
    
    
    kamathmanu's avatar
    kamathmanu committed
                      if (err) {
                              nhlog::net()->error(
                                "Failed to retrieve rooms from mtxclient - {} - {} - {}",
                                mtx::errors::to_string(err->matrix_error.errcode),
                                err->matrix_error.error,
                                err->parse_error);
                      } else if (req.filter.generic_search_term == this->userSearchString_ &&
                                 req.since == this->prevBatch_ && requested_server == this->server_) {
                              nhlog::net()->debug("signalling chunk to GUI thread");
    
                              emit fetchedRoomsBatch(res.chunk, res.next_batch);
    
    kamathmanu's avatar
    kamathmanu committed
                      }
              },
              requested_server);
    
    }
    
    void
    RoomDirectoryModel::displayRooms(std::vector<mtx::responses::PublicRoomsChunk> fetched_rooms,
    
    kamathmanu's avatar
    kamathmanu committed
                                     const std::string &next_batch)
    
            nhlog::net()->debug("Prev batch: {} | Next batch: {}", prevBatch_, next_batch);
    
    kamathmanu's avatar
    kamathmanu committed
    
            if (fetched_rooms.empty()) {
                    nhlog::net()->error("mtxclient helper thread yielded empty chunk!");
                    return;
            }
    
            beginInsertRows(QModelIndex(),
                            static_cast<int>(publicRoomsData_.size()),
                            static_cast<int>(publicRoomsData_.size() + fetched_rooms.size()) - 1);
            this->publicRoomsData_.insert(
              this->publicRoomsData_.end(), fetched_rooms.begin(), fetched_rooms.end());
            endInsertRows();
    
            if (next_batch.empty()) {
                    canFetchMore_ = false;
    
    		reachedEndOfPagination_ = true;
    		emit reachedEndOfPaginationChanged();
    
    kamathmanu's avatar
    kamathmanu committed
            }
    
    
    kamathmanu's avatar
    kamathmanu committed
            prevBatch_ = next_batch;
    
    
    	nhlog::ui()->debug ("Finished loading rooms");