diff options
author | DeepBlueV7.X <nicolas.werner@hotmail.de> | 2021-08-17 11:56:47 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-17 11:56:47 +0000 |
commit | b01496f9b48481cba71fc588c9f452c601d948ba (patch) | |
tree | 25403735cbfc5b645c039bd4f0e1f19a7a79ae61 /src/RoomDirectoryModel.cpp | |
parent | Remove unneeded code (diff) | |
parent | Formatting (diff) | |
download | nheko-b01496f9b48481cba71fc588c9f452c601d948ba.tar.xz |
Merge pull request #659 from kamathmanu/nhekoRoomDirectory
Nheko room directory
Diffstat (limited to 'src/RoomDirectoryModel.cpp')
-rw-r--r-- | src/RoomDirectoryModel.cpp | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/src/RoomDirectoryModel.cpp b/src/RoomDirectoryModel.cpp new file mode 100644 index 00000000..61c3eb72 --- /dev/null +++ b/src/RoomDirectoryModel.cpp @@ -0,0 +1,194 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "RoomDirectoryModel.h" +#include "Cache.h" +#include "ChatPage.h" + +#include <algorithm> + +RoomDirectoryModel::RoomDirectoryModel(QObject *parent, const std::string &s) + : QAbstractListModel(parent) + , server_(s) +{ + connect(this, + &RoomDirectoryModel::fetchedRoomsBatch, + this, + &RoomDirectoryModel::displayRooms, + Qt::QueuedConnection); +} + +QHash<int, QByteArray> +RoomDirectoryModel::roleNames() const +{ + return { + {Roles::Name, "name"}, + {Roles::Id, "roomid"}, + {Roles::AvatarUrl, "avatarUrl"}, + {Roles::Topic, "topic"}, + {Roles::MemberCount, "numMembers"}, + {Roles::Previewable, "canPreview"}, + }; +} + +void +RoomDirectoryModel::resetDisplayedData() +{ + beginResetModel(); + + prevBatch_ = ""; + nextBatch_ = ""; + canFetchMore_ = true; + + publicRoomsData_.clear(); + + endResetModel(); +} + +void +RoomDirectoryModel::setMatrixServer(const QString &s) +{ + server_ = s.toStdString(); + + nhlog::ui()->debug("Received matrix server: {}", server_); + + resetDisplayedData(); +} + +void +RoomDirectoryModel::setSearchTerm(const QString &f) +{ + userSearchString_ = f.toStdString(); + + nhlog::ui()->debug("Received user query: {}", userSearchString_); + + resetDisplayedData(); +} + +bool +RoomDirectoryModel::canJoinRoom(const QByteArray &room) +{ + const QString room_id(room); + return !room_id.isEmpty() && !cache::getRoomInfo({room_id.toStdString()}).count(room_id); +} + +std::vector<std::string> +RoomDirectoryModel::getViasForRoom(const std::vector<std::string> &aliases) +{ + std::vector<std::string> vias; + + vias.reserve(aliases.size()); + + std::transform(aliases.begin(), + aliases.end(), + std::back_inserter(vias), + [](const auto &alias) { return alias.substr(alias.find(":") + 1); }); + + return vias; +} + +void +RoomDirectoryModel::joinRoom(const int &index) +{ + 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 +{ + 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); + } + } + return {}; +} + +void +RoomDirectoryModel::fetchMore(const QModelIndex &) +{ + if (!canFetchMore_) + return; + + 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(); + + http::client()->post_public_rooms( + req, + [requested_server, this, req](const mtx::responses::PublicRooms &res, + mtx::http::RequestErr err) { + loadingMoreRooms_ = false; + emit loadingMoreRoomsChanged(); + + 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); + } + }, + requested_server); +} + +void +RoomDirectoryModel::displayRooms(std::vector<mtx::responses::PublicRoomsChunk> fetched_rooms, + const std::string &next_batch) +{ + nhlog::net()->debug("Prev batch: {} | Next batch: {}", prevBatch_, next_batch); + + 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(); + } + + prevBatch_ = next_batch; + + nhlog::ui()->debug("Finished loading rooms"); +} |