diff options
author | Nicolas Werner <nicolas.werner@hotmail.de> | 2021-08-17 14:22:37 +0200 |
---|---|---|
committer | Nicolas Werner <nicolas.werner@hotmail.de> | 2021-08-17 14:22:37 +0200 |
commit | 995b62122ad5a239c776adb52d9235ec3c04f83b (patch) | |
tree | 401bc13179e2ac6713fbfdb93f90c0d61b80e706 | |
parent | Update join button in room directory after join (diff) | |
download | nheko-995b62122ad5a239c776adb52d9235ec3c04f83b.tar.xz |
Fi lineendings
-rw-r--r-- | src/RoomDirectoryModel.cpp | 418 | ||||
-rw-r--r-- | src/RoomDirectoryModel.h | 196 |
2 files changed, 307 insertions, 307 deletions
diff --git a/src/RoomDirectoryModel.cpp b/src/RoomDirectoryModel.cpp index 14e0fe84..de5d430a 100644 --- a/src/RoomDirectoryModel.cpp +++ b/src/RoomDirectoryModel.cpp @@ -1,209 +1,209 @@ -// 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 &server) - : QAbstractListModel(parent) - , server_(server) -{ - connect(ChatPage::instance(), &ChatPage::newRoom, this, [this](const QString &roomid) { - auto roomid_ = roomid.toStdString(); - - int i = 0; - for (const auto &room : publicRoomsData_) { - if (room.room_id == roomid_) { - emit dataChanged(index(i), index(i), {Roles::CanJoin}); - break; - } - i++; - } - }); - - 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"}, - {Roles::CanJoin, "canJoin"}, - }; -} - -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 QString &room) const -{ - return !room.isEmpty() && cache::getRoomInfo({room.toStdString()}).empty(); -} - -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); - case Roles::CanJoin: - return canJoinRoom(QString::fromStdString(room_chunk.room_id)); - } - } - 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"); -} +// 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 &server) + : QAbstractListModel(parent) + , server_(server) +{ + connect(ChatPage::instance(), &ChatPage::newRoom, this, [this](const QString &roomid) { + auto roomid_ = roomid.toStdString(); + + int i = 0; + for (const auto &room : publicRoomsData_) { + if (room.room_id == roomid_) { + emit dataChanged(index(i), index(i), {Roles::CanJoin}); + break; + } + i++; + } + }); + + 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"}, + {Roles::CanJoin, "canJoin"}, + }; +} + +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 QString &room) const +{ + return !room.isEmpty() && cache::getRoomInfo({room.toStdString()}).empty(); +} + +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); + case Roles::CanJoin: + return canJoinRoom(QString::fromStdString(room_chunk.room_id)); + } + } + 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"); +} diff --git a/src/RoomDirectoryModel.h b/src/RoomDirectoryModel.h index 0bec3943..80c04612 100644 --- a/src/RoomDirectoryModel.h +++ b/src/RoomDirectoryModel.h @@ -1,98 +1,98 @@ -// SPDX-FileCopyrightText: 2021 Nheko Contributors -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include <QAbstractListModel> -#include <QHash> -#include <QString> -#include <string> -#include <vector> - -#include "MatrixClient.h" -#include <mtx/responses/public_rooms.hpp> -#include <mtxclient/http/errors.hpp> - -#include "Logging.h" - -namespace mtx::http { -using RequestErr = const std::optional<mtx::http::ClientError> &; -} -namespace mtx::responses { -struct PublicRooms; -} - -class RoomDirectoryModel : public QAbstractListModel -{ - Q_OBJECT - - Q_PROPERTY(bool loadingMoreRooms READ loadingMoreRooms NOTIFY loadingMoreRoomsChanged) - Q_PROPERTY(bool reachedEndOfPagination READ reachedEndOfPagination NOTIFY - reachedEndOfPaginationChanged) - -public: - explicit RoomDirectoryModel(QObject *parent = nullptr, const std::string &server = ""); - - enum Roles - { - Name = Qt::UserRole, - Id, - AvatarUrl, - Topic, - MemberCount, - Previewable, - CanJoin, - }; - QHash<int, QByteArray> roleNames() const override; - - QVariant data(const QModelIndex &index, int role) const override; - - inline int rowCount(const QModelIndex &parent = QModelIndex()) const override - { - (void)parent; - return static_cast<int>(publicRoomsData_.size()); - } - - bool canFetchMore(const QModelIndex &) const override { return canFetchMore_; } - - bool loadingMoreRooms() const { return loadingMoreRooms_; } - - bool reachedEndOfPagination() const { return reachedEndOfPagination_; } - - void fetchMore(const QModelIndex &) override; - - Q_INVOKABLE void joinRoom(const int &index = -1); - -signals: - void fetchedRoomsBatch(std::vector<mtx::responses::PublicRoomsChunk> rooms, - const std::string &next_batch); - void loadingMoreRoomsChanged(); - void reachedEndOfPaginationChanged(); - -public slots: - void setMatrixServer(const QString &s = ""); - void setSearchTerm(const QString &f); - -private slots: - - void displayRooms(std::vector<mtx::responses::PublicRoomsChunk> rooms, - const std::string &next_batch); - -private: - bool canJoinRoom(const QString &room) const; - - static constexpr size_t limit_ = 50; - - std::string server_; - std::string userSearchString_; - std::string prevBatch_; - std::string nextBatch_; - bool canFetchMore_{true}; - bool loadingMoreRooms_{false}; - bool reachedEndOfPagination_{false}; - std::vector<mtx::responses::PublicRoomsChunk> publicRoomsData_; - - std::vector<std::string> getViasForRoom(const std::vector<std::string> &room); - void resetDisplayedData(); -}; +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include <QAbstractListModel> +#include <QHash> +#include <QString> +#include <string> +#include <vector> + +#include "MatrixClient.h" +#include <mtx/responses/public_rooms.hpp> +#include <mtxclient/http/errors.hpp> + +#include "Logging.h" + +namespace mtx::http { +using RequestErr = const std::optional<mtx::http::ClientError> &; +} +namespace mtx::responses { +struct PublicRooms; +} + +class RoomDirectoryModel : public QAbstractListModel +{ + Q_OBJECT + + Q_PROPERTY(bool loadingMoreRooms READ loadingMoreRooms NOTIFY loadingMoreRoomsChanged) + Q_PROPERTY(bool reachedEndOfPagination READ reachedEndOfPagination NOTIFY + reachedEndOfPaginationChanged) + +public: + explicit RoomDirectoryModel(QObject *parent = nullptr, const std::string &server = ""); + + enum Roles + { + Name = Qt::UserRole, + Id, + AvatarUrl, + Topic, + MemberCount, + Previewable, + CanJoin, + }; + QHash<int, QByteArray> roleNames() const override; + + QVariant data(const QModelIndex &index, int role) const override; + + inline int rowCount(const QModelIndex &parent = QModelIndex()) const override + { + (void)parent; + return static_cast<int>(publicRoomsData_.size()); + } + + bool canFetchMore(const QModelIndex &) const override { return canFetchMore_; } + + bool loadingMoreRooms() const { return loadingMoreRooms_; } + + bool reachedEndOfPagination() const { return reachedEndOfPagination_; } + + void fetchMore(const QModelIndex &) override; + + Q_INVOKABLE void joinRoom(const int &index = -1); + +signals: + void fetchedRoomsBatch(std::vector<mtx::responses::PublicRoomsChunk> rooms, + const std::string &next_batch); + void loadingMoreRoomsChanged(); + void reachedEndOfPaginationChanged(); + +public slots: + void setMatrixServer(const QString &s = ""); + void setSearchTerm(const QString &f); + +private slots: + + void displayRooms(std::vector<mtx::responses::PublicRoomsChunk> rooms, + const std::string &next_batch); + +private: + bool canJoinRoom(const QString &room) const; + + static constexpr size_t limit_ = 50; + + std::string server_; + std::string userSearchString_; + std::string prevBatch_; + std::string nextBatch_; + bool canFetchMore_{true}; + bool loadingMoreRooms_{false}; + bool reachedEndOfPagination_{false}; + std::vector<mtx::responses::PublicRoomsChunk> publicRoomsData_; + + std::vector<std::string> getViasForRoom(const std::vector<std::string> &room); + void resetDisplayedData(); +}; |