From 0d700d99339ff4c921a7d242427fdd1f3c1d4c0b Mon Sep 17 00:00:00 2001 From: kamathmanu Date: Wed, 28 Jul 2021 22:29:57 -0400 Subject: [PATCH 01/17] Implemented Room Directory model to store and provide QML view with public room data from mtxclient --- CMakeLists.txt | 2 + src/RoomDirectoryModel.cpp | 171 +++++++++++++++++++++++++++ src/RoomDirectoryModel.h | 85 +++++++++++++ src/timeline/TimelineViewManager.cpp | 8 ++ 4 files changed, 266 insertions(+) create mode 100644 src/RoomDirectoryModel.cpp create mode 100644 src/RoomDirectoryModel.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b26602c..587059fe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -361,6 +361,7 @@ set(SRC_FILES src/UserSettingsPage.cpp src/UsersModel.cpp src/RoomsModel.cpp + src/RoomDirectoryModel.cpp src/Utils.cpp src/WebRTCSession.cpp src/WelcomePage.cpp @@ -567,6 +568,7 @@ qt5_wrap_cpp(MOC_HEADERS src/UserSettingsPage.h src/UsersModel.h src/RoomsModel.h + src/RoomDirectoryModel.h src/WebRTCSession.h src/WelcomePage.h ) diff --git a/src/RoomDirectoryModel.cpp b/src/RoomDirectoryModel.cpp new file mode 100644 index 00000000..397871eb --- /dev/null +++ b/src/RoomDirectoryModel.cpp @@ -0,0 +1,171 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "RoomDirectoryModel.h" +#include "ChatPage.h" + +#include + +RoomDirectoryModel::RoomDirectoryModel(QObject *parent, const std::string &s) + : QAbstractListModel(parent) + , server_(s) + , canFetchMore_(true) +{ + connect(this, &RoomDirectoryModel::fetchedRoomsBatch, this, &RoomDirectoryModel::displayRooms, Qt::QueuedConnection); +} + +QHash +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; + + beginRemoveRows(QModelIndex(), 0 , static_cast (publicRoomsData_.size())); + publicRoomsData_.clear(); + endRemoveRows(); + + 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(); +} + +std::vector +RoomDirectoryModel::getViasForRoom(const std::vector &aliases) +{ + std::vector vias; + + vias.reserve(aliases.size()); + + std::transform(aliases.begin(), aliases.end(), + std::back_inserter(vias), [](const auto &alias) { + const auto roomAliasDelimiter = ":"; + return alias.substr(alias.find(roomAliasDelimiter) + 1); + }); + + return vias; +} + +void +RoomDirectoryModel::joinRoom(const int &index) +{ + if (index >= 0 && static_cast (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 &) +{ + nhlog::net()->debug("Fetching more rooms from mtxclient..."); + nhlog::net()->debug("Prev batch: {} | Next batch: {}", prevBatch_, nextBatch_); + + 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_; + + http::client()->post_public_rooms(req, [requested_server, this, req] + (const mtx::responses::PublicRooms &res, + mtx::http::RequestErr err) + { + 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.prev_batch, res.next_batch); + } + }, requested_server); +} + +void +RoomDirectoryModel::displayRooms(std::vector fetched_rooms, + const std::string &prev_batch, const std::string &next_batch) +{ + nhlog::net()->debug("Prev batch: {} | Next batch: {}", prevBatch_, nextBatch_); + nhlog::net()->debug("NP batch: {} | NN batch: {}", prev_batch, next_batch); + + if (fetched_rooms.empty()) { + nhlog::net()->error("mtxclient helper thread yielded empty chunk!"); + return; + } + + beginInsertRows(QModelIndex(), static_cast (publicRoomsData_.size()), static_cast (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; + } + + prevBatch_ = std::exchange(nextBatch_, next_batch); +} \ No newline at end of file diff --git a/src/RoomDirectoryModel.h b/src/RoomDirectoryModel.h new file mode 100644 index 00000000..125813da --- /dev/null +++ b/src/RoomDirectoryModel.h @@ -0,0 +1,85 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include +#include +#include +#include +#include + +#include "MatrixClient.h" +#include +#include + +#include "Logging.h" + +namespace mtx::http { +using RequestErr = const std::optional &; +} +namespace mtx::responses { +struct PublicRooms; +} + +class RoomDirectoryModel : public QAbstractListModel +{ + Q_OBJECT + +public: + explicit RoomDirectoryModel + (QObject *parent = nullptr, const std::string &s = ""); + + enum Roles { + Name = Qt::UserRole, + Id, + AvatarUrl, + Topic, + MemberCount, + Previewable + }; + QHash 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 (publicRoomsData_.size()); + } + + inline bool canFetchMore(const QModelIndex &) const override + { + nhlog::net()->debug("determining if can fetch more"); + return canFetchMore_; + } + void fetchMore(const QModelIndex &) override; + + Q_INVOKABLE void joinRoom(const int &index = -1); + +signals: + void fetchedRoomsBatch(std::vector rooms, + const std::string &prev_batch, const std::string &next_batch); + void serverChanged(); + void searchTermEntered(); + +public slots: + void displayRooms(std::vector rooms, + const std::string &prev, const std::string &next); + void setMatrixServer(const QString &s = ""); + void setSearchTerm(const QString &f); + +private: + static constexpr size_t limit_ = 50; + + std::string server_; + std::string userSearchString_; + std::string prevBatch_; + std::string nextBatch_; + bool canFetchMore_; + std::vector publicRoomsData_; + + std::vector getViasForRoom(const std::vector &room); + void resetDisplayedData(); +}; \ No newline at end of file diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index a6922be7..2e6c45ca 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -26,6 +26,8 @@ #include "MainWindow.h" #include "MatrixClient.h" #include "MxcImageProvider.h" +#include "ReadReceiptsModel.h" +#include "RoomDirectoryModel.h" #include "RoomsModel.h" #include "SingleImagePackModel.h" #include "UserSettingsPage.h" @@ -39,6 +41,7 @@ Q_DECLARE_METATYPE(mtx::events::collections::TimelineEvents) Q_DECLARE_METATYPE(std::vector) +Q_DECLARE_METATYPE(std::vector) namespace msgs = mtx::events::msg; @@ -150,6 +153,8 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par qRegisterMetaType(); qRegisterMetaType(); + qRegisterMetaType>(); + qmlRegisterUncreatableMetaObject(qml_mtx_events::staticMetaObject, "im.nheko", 1, @@ -273,6 +278,9 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par "EmojiCategory", "Error: Only enums"); + qmlRegisterType( + "im.nheko.RoomDirectoryModel", 1, 0, "RoomDirectoryModel"); + #ifdef USE_QUICK_VIEW view = new QQuickView(parent); container = QWidget::createWindowContainer(view, parent); From 93f8c24fc56013bc696323eac71a09119889541f Mon Sep 17 00:00:00 2001 From: kamathmanu Date: Wed, 28 Jul 2021 22:31:31 -0400 Subject: [PATCH 02/17] Room Directory UI for exploring and joining public rooms. V1: simplistic server + network facilities --- resources/qml/RoomDirectory.qml | 155 ++++++++++++++++++++++++++++++++ resources/qml/RoomList.qml | 12 +++ resources/res.qrc | 3 +- 3 files changed, 169 insertions(+), 1 deletion(-) create mode 100644 resources/qml/RoomDirectory.qml diff --git a/resources/qml/RoomDirectory.qml b/resources/qml/RoomDirectory.qml new file mode 100644 index 00000000..e6fc2b84 --- /dev/null +++ b/resources/qml/RoomDirectory.qml @@ -0,0 +1,155 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +import QtQuick 2.9 +import QtQuick.Controls 2.3 +import QtQuick.Layouts 1.3 +import im.nheko 1.0 +import im.nheko.RoomDirectoryModel 1.0 + +ApplicationWindow { + id: roomDirectoryWindow + visible: true + + x: MainWindow.x + (MainWindow.width / 2) - (width / 2) + y: MainWindow.y + (MainWindow.height / 2) - (height / 2) + minimumWidth: 650 + minimumHeight: 420 + palette: Nheko.colors + color: Nheko.colors.window + modality: Qt.WindowModal + flags: Qt.Dialog + title: qsTr("Explore Public Rooms") + + header: RowLayout { + id: searchBarLayout + spacing: Nheko.paddingMedium + width: parent.width + + implicitHeight: roomTextInput.height + + MatrixTextField { + id: roomSearch + + Layout.fillWidth: true + + font.pixelSize: fontMetrics.font.pixelSize + padding: Nheko.paddingSmall + color: Nheko.colors.text + placeholderText: qsTr("Search for public rooms") + onTextChanged: searchTimer.restart() + } + + Timer { + id: searchTimer + + interval: 350 + onTriggered: roomDirView.model.setSearchTerm(roomSearch.text) + } + } + + ListView { + id: roomDirView + anchors.fill: parent + height: parent.height - searchBarLayout.height + model: RoomDirectoryModel { + id: roomDir + } + delegate: Rectangle { + id: roomDirDelegate + + property color background: Nheko.colors.window + property color importantText: Nheko.colors.text + property color unimportantText: Nheko.colors.buttonText + property int avatarSize: Math.ceil(fontMetrics.lineSpacing * 2.5) + + color: background + + height: avatarSize + 2.5 * Nheko.paddingMedium + width: ListView.view.width + + RowLayout { + + spacing: Nheko.paddingMedium + anchors.fill: parent + anchors.margins: Nheko.paddingMedium + implicitHeight: textContent.height + + Avatar { + id: roomAvatar + + Layout.alignment: Qt.AlignVCenter + width: avatarSize + height: avatarSize + url: model.avatarUrl.replace("mxc://", "image://MxcImage/") + displayName: model.name + } + + ColumnLayout { + id: textContent + + Layout.alignment: Qt.AlignLeft + Layout.fillWidth: true + width: parent.width - avatar.width + Layout.preferredWidth: parent.width - avatar.width + Layout.preferredHeight: roomNameRow.height + roomDescriptionRow.height + spacing: Nheko.paddingSmall + + RowLayout { + id: roomNameRow + Layout.fillWidth: true + spacing: 0 + + ElidedLabel { + Layout.alignment: Qt.AlignBottom + color: roomDirDelegate.importantText + elideWidth: textContent.width * 0.5 - Nheko.paddingMedium + font.pixelSize: fontMetrics.font.pixelSize * 1.1 + fullText: model.name + } + } + + RowLayout { + id: roomDescriptionRow + Layout.fillWidth: true + Layout.preferredWidth: parent.width + spacing: Nheko.paddingSmall + Layout.alignment: Qt.AlignLeft + Layout.preferredHeight: Math.max(roomTopic.height, roomCount.height, joinRoomButton.height) + + Label { + id: roomTopic + color: roomDirDelegate.unimportantText + font.weight: Font.Thin + font.pixelSize: fontMetrics.font.pixelSize + elide: Text.ElideRight + maximumLineCount: 2 + Layout.fillWidth: true + text: model.topic + verticalAlignment: Text.AlignVCenter + wrapMode: Text.WordWrap + } + + Label { + id: roomCount + color: roomDirDelegate.unimportantText + Layout.fillWidth: false + font.weight: Font.Thin + font.pixelSize: fontMetrics.font.pixelSize + text: model.numMembers.toString() + } + + Button { + id: joinRoomButton + Layout.fillWidth: false + text: "Join" + Layout.margins: Nheko.paddingSmall + onClicked: roomDir.joinRoom(model.index) + } + } + } + } + } + } +} diff --git a/resources/qml/RoomList.qml b/resources/qml/RoomList.qml index a2e50fab..31c9d3cf 100644 --- a/resources/qml/RoomList.qml +++ b/resources/qml/RoomList.qml @@ -16,6 +16,13 @@ Page { property int avatarSize: Math.ceil(fontMetrics.lineSpacing * 2.3) property bool collapsed: false +Component { + id: roomDirectoryComponent + + RoomDirectory { + } + } + ListView { id: roomlist @@ -549,6 +556,11 @@ Page { ToolTip.visible: hovered ToolTip.text: qsTr("Room directory") Layout.margins: Nheko.paddingMedium + onClicked: { + console.debug("Roomdir clicked"); + var win = roomDirectoryComponent.createObject(timelineRoot); + win.show(); + } } ImageButton { diff --git a/resources/res.qrc b/resources/res.qrc index 5d37c397..407a0a98 100644 --- a/resources/res.qrc +++ b/resources/res.qrc @@ -143,7 +143,8 @@ qml/emoji/EmojiPicker.qml qml/emoji/StickerPicker.qml qml/UserProfile.qml - qml/delegates/MessageDelegate.qml + qml/RoomDirectory.qml + qml/delegates/MessageDelegate.qml qml/delegates/TextMessage.qml qml/delegates/NoticeMessage.qml qml/delegates/ImageMessage.qml From 04d0d413e321f72f19ab443a2a3894254b7fb0aa Mon Sep 17 00:00:00 2001 From: kamathmanu Date: Wed, 28 Jul 2021 22:33:23 -0400 Subject: [PATCH 03/17] Linted code --- src/RoomDirectoryModel.cpp | 208 ++++++++++++++------------- src/RoomDirectoryModel.h | 94 ++++++------ src/timeline/TimelineViewManager.cpp | 4 +- 3 files changed, 157 insertions(+), 149 deletions(-) diff --git a/src/RoomDirectoryModel.cpp b/src/RoomDirectoryModel.cpp index 397871eb..2a06e4d4 100644 --- a/src/RoomDirectoryModel.cpp +++ b/src/RoomDirectoryModel.cpp @@ -8,164 +8,170 @@ #include RoomDirectoryModel::RoomDirectoryModel(QObject *parent, const std::string &s) - : QAbstractListModel(parent) - , server_(s) - , canFetchMore_(true) + : QAbstractListModel(parent) + , server_(s) + , canFetchMore_(true) { - connect(this, &RoomDirectoryModel::fetchedRoomsBatch, this, &RoomDirectoryModel::displayRooms, Qt::QueuedConnection); + connect(this, + &RoomDirectoryModel::fetchedRoomsBatch, + this, + &RoomDirectoryModel::displayRooms, + Qt::QueuedConnection); } -QHash +QHash RoomDirectoryModel::roleNames() const { - return { - {Roles::Name, "name"}, - {Roles::Id, "roomid"}, - {Roles::AvatarUrl, "avatarUrl"}, - {Roles::Topic, "topic"}, - {Roles::MemberCount, "numMembers"}, - {Roles::Previewable, "canPreview"},}; + return { + {Roles::Name, "name"}, + {Roles::Id, "roomid"}, + {Roles::AvatarUrl, "avatarUrl"}, + {Roles::Topic, "topic"}, + {Roles::MemberCount, "numMembers"}, + {Roles::Previewable, "canPreview"}, + }; } void RoomDirectoryModel::resetDisplayedData() { - beginResetModel(); + beginResetModel(); - prevBatch_ = ""; - nextBatch_ = ""; - canFetchMore_ = true; + prevBatch_ = ""; + nextBatch_ = ""; + canFetchMore_ = true; - beginRemoveRows(QModelIndex(), 0 , static_cast (publicRoomsData_.size())); - publicRoomsData_.clear(); - endRemoveRows(); + beginRemoveRows(QModelIndex(), 0, static_cast(publicRoomsData_.size())); + publicRoomsData_.clear(); + endRemoveRows(); - endResetModel(); + endResetModel(); } void RoomDirectoryModel::setMatrixServer(const QString &s) { - server_ = s.toStdString(); + server_ = s.toStdString(); - nhlog::ui()->debug("Received matrix server: {}", server_); + nhlog::ui()->debug("Received matrix server: {}", server_); - resetDisplayedData(); + resetDisplayedData(); } void RoomDirectoryModel::setSearchTerm(const QString &f) { - userSearchString_ = f.toStdString(); + userSearchString_ = f.toStdString(); - nhlog::ui()->debug("Received user query: {}", userSearchString_); + nhlog::ui()->debug("Received user query: {}", userSearchString_); - resetDisplayedData(); + resetDisplayedData(); } std::vector RoomDirectoryModel::getViasForRoom(const std::vector &aliases) { - std::vector vias; - - vias.reserve(aliases.size()); + std::vector vias; - std::transform(aliases.begin(), aliases.end(), - std::back_inserter(vias), [](const auto &alias) { - const auto roomAliasDelimiter = ":"; - return alias.substr(alias.find(roomAliasDelimiter) + 1); - }); + vias.reserve(aliases.size()); - return vias; + std::transform( + aliases.begin(), aliases.end(), std::back_inserter(vias), [](const auto &alias) { + const auto roomAliasDelimiter = ":"; + return alias.substr(alias.find(roomAliasDelimiter) + 1); + }); + + return vias; } void RoomDirectoryModel::joinRoom(const int &index) { - if (index >= 0 && static_cast (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)); - } + if (index >= 0 && static_cast(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); + 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 {}; + return {}; } void -RoomDirectoryModel::fetchMore(const QModelIndex &) +RoomDirectoryModel::fetchMore(const QModelIndex &) { - nhlog::net()->debug("Fetching more rooms from mtxclient..."); - nhlog::net()->debug("Prev batch: {} | Next batch: {}", prevBatch_, nextBatch_); + nhlog::net()->debug("Fetching more rooms from mtxclient..."); + nhlog::net()->debug("Prev batch: {} | Next batch: {}", prevBatch_, nextBatch_); - 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_; + 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_; - http::client()->post_public_rooms(req, [requested_server, this, req] - (const mtx::responses::PublicRooms &res, - mtx::http::RequestErr err) - { - 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.prev_batch, res.next_batch); - } - }, requested_server); + http::client()->post_public_rooms( + req, + [requested_server, this, req](const mtx::responses::PublicRooms &res, + mtx::http::RequestErr err) { + 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.prev_batch, res.next_batch); + } + }, + requested_server); } void RoomDirectoryModel::displayRooms(std::vector fetched_rooms, - const std::string &prev_batch, const std::string &next_batch) + const std::string &prev_batch, + const std::string &next_batch) { - nhlog::net()->debug("Prev batch: {} | Next batch: {}", prevBatch_, nextBatch_); - nhlog::net()->debug("NP batch: {} | NN batch: {}", prev_batch, next_batch); + nhlog::net()->debug("Prev batch: {} | Next batch: {}", prevBatch_, nextBatch_); + nhlog::net()->debug("NP batch: {} | NN batch: {}", prev_batch, next_batch); - if (fetched_rooms.empty()) { - nhlog::net()->error("mtxclient helper thread yielded empty chunk!"); - return; - } + if (fetched_rooms.empty()) { + nhlog::net()->error("mtxclient helper thread yielded empty chunk!"); + return; + } - beginInsertRows(QModelIndex(), static_cast (publicRoomsData_.size()), static_cast (publicRoomsData_.size() + fetched_rooms.size()) - 1); - this->publicRoomsData_.insert(this->publicRoomsData_.end(), fetched_rooms.begin(), fetched_rooms.end()); - endInsertRows(); + beginInsertRows(QModelIndex(), + static_cast(publicRoomsData_.size()), + static_cast(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; - } - - prevBatch_ = std::exchange(nextBatch_, next_batch); + if (next_batch.empty()) { + canFetchMore_ = false; + } + + prevBatch_ = std::exchange(nextBatch_, next_batch); } \ No newline at end of file diff --git a/src/RoomDirectoryModel.h b/src/RoomDirectoryModel.h index 125813da..ff571d93 100644 --- a/src/RoomDirectoryModel.h +++ b/src/RoomDirectoryModel.h @@ -7,12 +7,12 @@ #include #include #include -#include #include +#include #include "MatrixClient.h" -#include #include +#include #include "Logging.h" @@ -25,61 +25,63 @@ struct PublicRooms; class RoomDirectoryModel : public QAbstractListModel { - Q_OBJECT + Q_OBJECT -public: - explicit RoomDirectoryModel - (QObject *parent = nullptr, const std::string &s = ""); +public: + explicit RoomDirectoryModel(QObject *parent = nullptr, const std::string &s = ""); - enum Roles { - Name = Qt::UserRole, - Id, - AvatarUrl, - Topic, - MemberCount, - Previewable - }; - QHash roleNames() const override; + enum Roles + { + Name = Qt::UserRole, + Id, + AvatarUrl, + Topic, + MemberCount, + Previewable + }; + QHash roleNames() const override; - QVariant data(const QModelIndex &index, int role) 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 (publicRoomsData_.size()); - } + inline int rowCount(const QModelIndex &parent = QModelIndex()) const override + { + (void)parent; + return static_cast(publicRoomsData_.size()); + } - inline bool canFetchMore(const QModelIndex &) const override - { - nhlog::net()->debug("determining if can fetch more"); - return canFetchMore_; - } - void fetchMore(const QModelIndex &) override; + inline bool canFetchMore(const QModelIndex &) const override + { + nhlog::net()->debug("determining if can fetch more"); + return canFetchMore_; + } + void fetchMore(const QModelIndex &) override; - Q_INVOKABLE void joinRoom(const int &index = -1); + Q_INVOKABLE void joinRoom(const int &index = -1); signals: - void fetchedRoomsBatch(std::vector rooms, - const std::string &prev_batch, const std::string &next_batch); - void serverChanged(); - void searchTermEntered(); + void fetchedRoomsBatch(std::vector rooms, + const std::string &prev_batch, + const std::string &next_batch); + void serverChanged(); + void searchTermEntered(); public slots: - void displayRooms(std::vector rooms, - const std::string &prev, const std::string &next); - void setMatrixServer(const QString &s = ""); - void setSearchTerm(const QString &f); + void displayRooms(std::vector rooms, + const std::string &prev, + const std::string &next); + void setMatrixServer(const QString &s = ""); + void setSearchTerm(const QString &f); private: - static constexpr size_t limit_ = 50; - - std::string server_; - std::string userSearchString_; - std::string prevBatch_; - std::string nextBatch_; - bool canFetchMore_; - std::vector publicRoomsData_; + static constexpr size_t limit_ = 50; - std::vector getViasForRoom(const std::vector &room); - void resetDisplayedData(); + std::string server_; + std::string userSearchString_; + std::string prevBatch_; + std::string nextBatch_; + bool canFetchMore_; + std::vector publicRoomsData_; + + std::vector getViasForRoom(const std::vector &room); + void resetDisplayedData(); }; \ No newline at end of file diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index 2e6c45ca..fd5528d8 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -153,7 +153,7 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par qRegisterMetaType(); qRegisterMetaType(); - qRegisterMetaType>(); + qRegisterMetaType>(); qmlRegisterUncreatableMetaObject(qml_mtx_events::staticMetaObject, "im.nheko", @@ -278,7 +278,7 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par "EmojiCategory", "Error: Only enums"); - qmlRegisterType( + qmlRegisterType( "im.nheko.RoomDirectoryModel", 1, 0, "RoomDirectoryModel"); #ifdef USE_QUICK_VIEW From f5ee1e84b5e813bb7a98e4c92cf6648da2eb6fac Mon Sep 17 00:00:00 2001 From: kamathmanu Date: Sun, 1 Aug 2021 19:14:54 -0400 Subject: [PATCH 04/17] Padding for search bar --- resources/qml/RoomDirectory.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/RoomDirectory.qml b/resources/qml/RoomDirectory.qml index e6fc2b84..7298a7cd 100644 --- a/resources/qml/RoomDirectory.qml +++ b/resources/qml/RoomDirectory.qml @@ -27,7 +27,7 @@ ApplicationWindow { spacing: Nheko.paddingMedium width: parent.width - implicitHeight: roomTextInput.height + implicitHeight: roomSearch.height MatrixTextField { id: roomSearch @@ -35,7 +35,7 @@ ApplicationWindow { Layout.fillWidth: true font.pixelSize: fontMetrics.font.pixelSize - padding: Nheko.paddingSmall + padding: Math.ceil(1.5 * Nheko.paddingSmall) color: Nheko.colors.text placeholderText: qsTr("Search for public rooms") onTextChanged: searchTimer.restart() From d3d7844106a422bd54f899f210e54dcb43a26a4c Mon Sep 17 00:00:00 2001 From: kamathmanu Date: Tue, 3 Aug 2021 18:25:11 -0400 Subject: [PATCH 05/17] Made only unjoined rooms joinable --- src/RoomDirectoryModel.cpp | 13 ++++++++++++- src/RoomDirectoryModel.h | 3 ++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/RoomDirectoryModel.cpp b/src/RoomDirectoryModel.cpp index 2a06e4d4..b206bf9e 100644 --- a/src/RoomDirectoryModel.cpp +++ b/src/RoomDirectoryModel.cpp @@ -4,6 +4,7 @@ #include "RoomDirectoryModel.h" #include "ChatPage.h" +#include "Cache.h" #include @@ -68,6 +69,16 @@ RoomDirectoryModel::setSearchTerm(const QString &f) resetDisplayedData(); } + +bool +RoomDirectoryModel::canJoinRoom(const QByteArray &room) +{ + 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 RoomDirectoryModel::getViasForRoom(const std::vector &aliases) { @@ -174,4 +185,4 @@ RoomDirectoryModel::displayRooms(std::vector f } prevBatch_ = std::exchange(nextBatch_, next_batch); -} \ No newline at end of file +} diff --git a/src/RoomDirectoryModel.h b/src/RoomDirectoryModel.h index ff571d93..7099ff00 100644 --- a/src/RoomDirectoryModel.h +++ b/src/RoomDirectoryModel.h @@ -56,6 +56,7 @@ public: } void fetchMore(const QModelIndex &) override; + Q_INVOKABLE bool canJoinRoom(const QByteArray &room); Q_INVOKABLE void joinRoom(const int &index = -1); signals: @@ -84,4 +85,4 @@ private: std::vector getViasForRoom(const std::vector &room); void resetDisplayedData(); -}; \ No newline at end of file +}; From 98b733ad26e9cb6a82e8592ac0d40959a0c1a1f5 Mon Sep 17 00:00:00 2001 From: kamathmanu Date: Tue, 3 Aug 2021 18:26:11 -0400 Subject: [PATCH 06/17] Fixed anchoring/positioning of delegate items and join room display --- resources/qml/RoomDirectory.qml | 35 +++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/resources/qml/RoomDirectory.qml b/resources/qml/RoomDirectory.qml index 7298a7cd..94bfceb2 100644 --- a/resources/qml/RoomDirectory.qml +++ b/resources/qml/RoomDirectory.qml @@ -62,7 +62,7 @@ ApplicationWindow { property color background: Nheko.colors.window property color importantText: Nheko.colors.text property color unimportantText: Nheko.colors.buttonText - property int avatarSize: Math.ceil(fontMetrics.lineSpacing * 2.5) + property int avatarSize: Math.ceil(fontMetrics.lineSpacing * 4) color: background @@ -115,13 +115,14 @@ ApplicationWindow { Layout.fillWidth: true Layout.preferredWidth: parent.width spacing: Nheko.paddingSmall - Layout.alignment: Qt.AlignLeft - Layout.preferredHeight: Math.max(roomTopic.height, roomCount.height, joinRoomButton.height) + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + Layout.preferredHeight: Math.ceil(fontMetrics.lineSpacing * 4) Label { id: roomTopic color: roomDirDelegate.unimportantText font.weight: Font.Thin + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft font.pixelSize: fontMetrics.font.pixelSize elide: Text.ElideRight maximumLineCount: 2 @@ -130,23 +131,37 @@ ApplicationWindow { verticalAlignment: Text.AlignVCenter wrapMode: Text.WordWrap } + Item { + id: numMembersRectangle + Layout.fillWidth: false + Layout.margins: Nheko.paddingSmall + width: roomCount.width Label { id: roomCount color: roomDirDelegate.unimportantText + anchors.centerIn: parent Layout.fillWidth: false font.weight: Font.Thin font.pixelSize: fontMetrics.font.pixelSize text: model.numMembers.toString() } + } - Button { - id: joinRoomButton - Layout.fillWidth: false - text: "Join" - Layout.margins: Nheko.paddingSmall - onClicked: roomDir.joinRoom(model.index) - } + Item { + id: buttonRectangle + Layout.fillWidth: false + Layout.margins: Nheko.paddingSmall + width: joinRoomButton.width + Button { + id: joinRoomButton + visible: roomDir.canJoinRoom(model.roomid) + anchors.centerIn: parent + width: Math.ceil(0.1 * roomDirectoryWindow.width) + text: "Join" + onClicked: roomDir.joinRoom(model.index) + } + } } } } From 4ec0c8c9bb384dcaeb9c18bb359cbd4e1e95e9c1 Mon Sep 17 00:00:00 2001 From: kamathmanu Date: Wed, 4 Aug 2021 14:12:10 -0400 Subject: [PATCH 07/17] make lint --- src/RoomDirectoryModel.cpp | 11 +++++------ src/RoomDirectoryModel.h | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/RoomDirectoryModel.cpp b/src/RoomDirectoryModel.cpp index b206bf9e..6cb7a4fb 100644 --- a/src/RoomDirectoryModel.cpp +++ b/src/RoomDirectoryModel.cpp @@ -3,8 +3,8 @@ // SPDX-License-Identifier: GPL-3.0-or-later #include "RoomDirectoryModel.h" -#include "ChatPage.h" #include "Cache.h" +#include "ChatPage.h" #include @@ -69,14 +69,13 @@ RoomDirectoryModel::setSearchTerm(const QString &f) resetDisplayedData(); } - bool RoomDirectoryModel::canJoinRoom(const QByteArray &room) { - 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); + 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 diff --git a/src/RoomDirectoryModel.h b/src/RoomDirectoryModel.h index 7099ff00..c7089a1e 100644 --- a/src/RoomDirectoryModel.h +++ b/src/RoomDirectoryModel.h @@ -56,7 +56,7 @@ public: } void fetchMore(const QModelIndex &) override; - Q_INVOKABLE bool canJoinRoom(const QByteArray &room); + Q_INVOKABLE bool canJoinRoom(const QByteArray &room); Q_INVOKABLE void joinRoom(const int &index = -1); signals: From 34ffe054cf767a15f03d30b4839f08144648080f Mon Sep 17 00:00:00 2001 From: kamathmanu Date: Sat, 7 Aug 2021 15:08:38 -0400 Subject: [PATCH 08/17] Improve window closing --- resources/qml/RoomDirectory.qml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/resources/qml/RoomDirectory.qml b/resources/qml/RoomDirectory.qml index 94bfceb2..f31df64d 100644 --- a/resources/qml/RoomDirectory.qml +++ b/resources/qml/RoomDirectory.qml @@ -19,9 +19,14 @@ ApplicationWindow { palette: Nheko.colors color: Nheko.colors.window modality: Qt.WindowModal - flags: Qt.Dialog + flags: Qt.Dialog | Qt.WindowCloseButtonHint title: qsTr("Explore Public Rooms") + Shortcut { + sequence: StandardKey.Cancel + onActivated: roomDirectoryWindow.close() + } + header: RowLayout { id: searchBarLayout spacing: Nheko.paddingMedium From 14f8f4d61b45f0f2fd304a87f291a83781142615 Mon Sep 17 00:00:00 2001 From: kamathmanu Date: Sat, 7 Aug 2021 17:13:18 -0400 Subject: [PATCH 09/17] Fix Duplicate fetched chunk --- src/RoomDirectoryModel.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/RoomDirectoryModel.cpp b/src/RoomDirectoryModel.cpp index 6cb7a4fb..06bd9d8a 100644 --- a/src/RoomDirectoryModel.cpp +++ b/src/RoomDirectoryModel.cpp @@ -131,7 +131,6 @@ void RoomDirectoryModel::fetchMore(const QModelIndex &) { nhlog::net()->debug("Fetching more rooms from mtxclient..."); - nhlog::net()->debug("Prev batch: {} | Next batch: {}", prevBatch_, nextBatch_); mtx::requests::PublicRooms req; req.limit = limit_; @@ -183,5 +182,5 @@ RoomDirectoryModel::displayRooms(std::vector f canFetchMore_ = false; } - prevBatch_ = std::exchange(nextBatch_, next_batch); + prevBatch_ = next_batch; } From 6a75e5270cd12aebc6130f0bc3ee1d9999620601 Mon Sep 17 00:00:00 2001 From: kamathmanu Date: Mon, 9 Aug 2021 09:18:08 -0400 Subject: [PATCH 10/17] Fix nits from code review --- CMakeLists.txt | 4 ++-- resources/qml/RoomDirectory.qml | 8 +++----- resources/qml/RoomList.qml | 1 - resources/res.qrc | 5 ----- src/RoomDirectoryModel.cpp | 5 +---- src/RoomDirectoryModel.h | 1 - src/timeline/TimelineViewManager.cpp | 2 +- 7 files changed, 7 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bcf31b41..cafe7948 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -359,8 +359,8 @@ set(SRC_FILES src/TrayIcon.cpp src/UserSettingsPage.cpp src/UsersModel.cpp - src/RoomsModel.cpp src/RoomDirectoryModel.cpp + src/RoomsModel.cpp src/Utils.cpp src/WebRTCSession.cpp src/WelcomePage.cpp @@ -565,8 +565,8 @@ qt5_wrap_cpp(MOC_HEADERS src/TrayIcon.h src/UserSettingsPage.h src/UsersModel.h - src/RoomsModel.h src/RoomDirectoryModel.h + src/RoomsModel.h src/WebRTCSession.h src/WelcomePage.h src/ReadReceiptsModel.h diff --git a/resources/qml/RoomDirectory.qml b/resources/qml/RoomDirectory.qml index f31df64d..b01c1e00 100644 --- a/resources/qml/RoomDirectory.qml +++ b/resources/qml/RoomDirectory.qml @@ -6,7 +6,6 @@ import QtQuick 2.9 import QtQuick.Controls 2.3 import QtQuick.Layouts 1.3 import im.nheko 1.0 -import im.nheko.RoomDirectoryModel 1.0 ApplicationWindow { id: roomDirectoryWindow @@ -40,7 +39,7 @@ ApplicationWindow { Layout.fillWidth: true font.pixelSize: fontMetrics.font.pixelSize - padding: Math.ceil(1.5 * Nheko.paddingSmall) + padding: Nheko.paddingMedium color: Nheko.colors.text placeholderText: qsTr("Search for public rooms") onTextChanged: searchTimer.restart() @@ -57,7 +56,6 @@ ApplicationWindow { ListView { id: roomDirView anchors.fill: parent - height: parent.height - searchBarLayout.height model: RoomDirectoryModel { id: roomDir } @@ -67,7 +65,7 @@ ApplicationWindow { property color background: Nheko.colors.window property color importantText: Nheko.colors.text property color unimportantText: Nheko.colors.buttonText - property int avatarSize: Math.ceil(fontMetrics.lineSpacing * 4) + property int avatarSize: fontMetrics.lineSpacing * 4 color: background @@ -121,7 +119,7 @@ ApplicationWindow { Layout.preferredWidth: parent.width spacing: Nheko.paddingSmall Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft - Layout.preferredHeight: Math.ceil(fontMetrics.lineSpacing * 4) + Layout.preferredHeight: fontMetrics.lineSpacing * 4 Label { id: roomTopic diff --git a/resources/qml/RoomList.qml b/resources/qml/RoomList.qml index e8aacf75..6074f063 100644 --- a/resources/qml/RoomList.qml +++ b/resources/qml/RoomList.qml @@ -565,7 +565,6 @@ Component { ToolTip.text: qsTr("Room directory") Layout.margins: Nheko.paddingMedium onClicked: { - console.debug("Roomdir clicked"); var win = roomDirectoryComponent.createObject(timelineRoot); win.show(); } diff --git a/resources/res.qrc b/resources/res.qrc index 3e417d4c..b46b726c 100644 --- a/resources/res.qrc +++ b/resources/res.qrc @@ -143,11 +143,6 @@ qml/emoji/StickerPicker.qml qml/UserProfile.qml qml/RoomDirectory.qml - qml/delegates/MessageDelegate.qml - qml/delegates/TextMessage.qml - qml/delegates/NoticeMessage.qml - qml/delegates/ImageMessage.qml - qml/delegates/PlayableMediaMessage.qml qml/delegates/MessageDelegate.qml qml/delegates/Encrypted.qml qml/delegates/FileMessage.qml diff --git a/src/RoomDirectoryModel.cpp b/src/RoomDirectoryModel.cpp index 06bd9d8a..2c633491 100644 --- a/src/RoomDirectoryModel.cpp +++ b/src/RoomDirectoryModel.cpp @@ -42,9 +42,7 @@ RoomDirectoryModel::resetDisplayedData() nextBatch_ = ""; canFetchMore_ = true; - beginRemoveRows(QModelIndex(), 0, static_cast(publicRoomsData_.size())); publicRoomsData_.clear(); - endRemoveRows(); endResetModel(); } @@ -87,8 +85,7 @@ RoomDirectoryModel::getViasForRoom(const std::vector &aliases) std::transform( aliases.begin(), aliases.end(), std::back_inserter(vias), [](const auto &alias) { - const auto roomAliasDelimiter = ":"; - return alias.substr(alias.find(roomAliasDelimiter) + 1); + return alias.substr(alias.find(":") + 1); }); return vias; diff --git a/src/RoomDirectoryModel.h b/src/RoomDirectoryModel.h index c7089a1e..952ae3ff 100644 --- a/src/RoomDirectoryModel.h +++ b/src/RoomDirectoryModel.h @@ -51,7 +51,6 @@ public: inline bool canFetchMore(const QModelIndex &) const override { - nhlog::net()->debug("determining if can fetch more"); return canFetchMore_; } void fetchMore(const QModelIndex &) override; diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index da68d503..ff60856a 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -287,7 +287,7 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par "Error: Only enums"); qmlRegisterType( - "im.nheko.RoomDirectoryModel", 1, 0, "RoomDirectoryModel"); + "im.nheko", 1, 0, "RoomDirectoryModel"); #ifdef USE_QUICK_VIEW view = new QQuickView(parent); From 570e5ffde236056ad5c70a59681ad6fc1e445717 Mon Sep 17 00:00:00 2001 From: kamathmanu Date: Thu, 12 Aug 2021 09:50:52 -0400 Subject: [PATCH 11/17] Added Spinner while rooms load --- resources/qml/RoomDirectory.qml | 33 +++++++++++++++++++++++++++------ src/RoomDirectoryModel.cpp | 22 +++++++++++++++++----- src/RoomDirectoryModel.h | 22 +++++++++++++++------- 3 files changed, 59 insertions(+), 18 deletions(-) diff --git a/resources/qml/RoomDirectory.qml b/resources/qml/RoomDirectory.qml index b01c1e00..65685b9a 100644 --- a/resources/qml/RoomDirectory.qml +++ b/resources/qml/RoomDirectory.qml @@ -2,6 +2,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later +import "./ui" import QtQuick 2.9 import QtQuick.Controls 2.3 import QtQuick.Layouts 1.3 @@ -11,6 +12,8 @@ ApplicationWindow { id: roomDirectoryWindow visible: true + property RoomDirectoryModel publicRooms : RoomDirectoryModel {} + x: MainWindow.x + (MainWindow.width / 2) - (width / 2) y: MainWindow.y + (MainWindow.height / 2) - (height / 2) minimumWidth: 650 @@ -56,9 +59,7 @@ ApplicationWindow { ListView { id: roomDirView anchors.fill: parent - model: RoomDirectoryModel { - id: roomDir - } + model: publicRooms delegate: Rectangle { id: roomDirDelegate @@ -158,16 +159,36 @@ ApplicationWindow { width: joinRoomButton.width Button { id: joinRoomButton - visible: roomDir.canJoinRoom(model.roomid) + visible: publicRooms.canJoinRoom(model.roomid) anchors.centerIn: parent width: Math.ceil(0.1 * roomDirectoryWindow.width) text: "Join" - onClicked: roomDir.joinRoom(model.index) + onClicked: publicRooms.joinRoom(model.index) } } } } } - } + } + + footer: Item { + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width + visible: (publicRooms.reachedEndOfPagination == false) && publicRooms.loadingMoreRooms + // hacky but works + height: loadingSpinner.height + 2 * Nheko.paddingLarge + anchors.margins: Nheko.paddingLarge + + Spinner { + id: loadingSpinner + + anchors.centerIn: parent + anchors.margins: Nheko.paddingLarge + running: visible + foreground: Nheko.colors.mid + z: 7 + } + } + } } diff --git a/src/RoomDirectoryModel.cpp b/src/RoomDirectoryModel.cpp index 2c633491..7d6be13e 100644 --- a/src/RoomDirectoryModel.cpp +++ b/src/RoomDirectoryModel.cpp @@ -11,7 +11,6 @@ RoomDirectoryModel::RoomDirectoryModel(QObject *parent, const std::string &s) : QAbstractListModel(parent) , server_(s) - , canFetchMore_(true) { connect(this, &RoomDirectoryModel::fetchedRoomsBatch, @@ -127,6 +126,8 @@ RoomDirectoryModel::data(const QModelIndex &index, int role) const void RoomDirectoryModel::fetchMore(const QModelIndex &) { + if (!canFetchMore_) return; + nhlog::net()->debug("Fetching more rooms from mtxclient..."); mtx::requests::PublicRooms req; @@ -136,10 +137,19 @@ RoomDirectoryModel::fetchMore(const QModelIndex &) // 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 - {} - {} - {}", @@ -149,7 +159,7 @@ RoomDirectoryModel::fetchMore(const QModelIndex &) } 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.prev_batch, res.next_batch); + emit fetchedRoomsBatch(res.chunk, res.next_batch); } }, requested_server); @@ -157,11 +167,9 @@ RoomDirectoryModel::fetchMore(const QModelIndex &) void RoomDirectoryModel::displayRooms(std::vector fetched_rooms, - const std::string &prev_batch, const std::string &next_batch) { - nhlog::net()->debug("Prev batch: {} | Next batch: {}", prevBatch_, nextBatch_); - nhlog::net()->debug("NP batch: {} | NN batch: {}", prev_batch, 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!"); @@ -177,7 +185,11 @@ RoomDirectoryModel::displayRooms(std::vector f 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 952ae3ff..a7e6c0bc 100644 --- a/src/RoomDirectoryModel.h +++ b/src/RoomDirectoryModel.h @@ -27,6 +27,9 @@ 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 &s = ""); @@ -49,10 +52,15 @@ public: return static_cast(publicRoomsData_.size()); } - inline bool canFetchMore(const QModelIndex &) const override + 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 bool canJoinRoom(const QByteArray &room); @@ -60,15 +68,13 @@ public: signals: void fetchedRoomsBatch(std::vector rooms, - const std::string &prev_batch, const std::string &next_batch); - void serverChanged(); - void searchTermEntered(); + void loadingMoreRoomsChanged(); + void reachedEndOfPaginationChanged(); public slots: void displayRooms(std::vector rooms, - const std::string &prev, - const std::string &next); + const std::string &next_batch); void setMatrixServer(const QString &s = ""); void setSearchTerm(const QString &f); @@ -79,7 +85,9 @@ private: std::string userSearchString_; std::string prevBatch_; std::string nextBatch_; - bool canFetchMore_; + bool canFetchMore_ {true}; + bool loadingMoreRooms_ {false}; + bool reachedEndOfPagination_ {false}; std::vector publicRoomsData_; std::vector getViasForRoom(const std::vector &room); From f2560b7531aeb97d4c581fcc19205d192606a2d2 Mon Sep 17 00:00:00 2001 From: kamathmanu Date: Thu, 12 Aug 2021 09:57:26 -0400 Subject: [PATCH 12/17] Make search text selectable by clicking --- resources/qml/RoomDirectory.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/qml/RoomDirectory.qml b/resources/qml/RoomDirectory.qml index 65685b9a..a3c3d4da 100644 --- a/resources/qml/RoomDirectory.qml +++ b/resources/qml/RoomDirectory.qml @@ -40,6 +40,7 @@ ApplicationWindow { id: roomSearch Layout.fillWidth: true + selectByMouse: true font.pixelSize: fontMetrics.font.pixelSize padding: Nheko.paddingMedium From 9ab129613177f974afd10070e3a7d065d7aebbfa Mon Sep 17 00:00:00 2001 From: kamathmanu Date: Thu, 12 Aug 2021 10:45:42 -0400 Subject: [PATCH 13/17] Ran qmlformat and make license --- resources/qml/RoomDirectory.qml | 411 ++++++++++++++------------- src/RoomDirectoryModel.cpp | 31 +- src/RoomDirectoryModel.h | 24 +- src/timeline/TimelineViewManager.cpp | 3 +- 4 files changed, 244 insertions(+), 225 deletions(-) diff --git a/resources/qml/RoomDirectory.qml b/resources/qml/RoomDirectory.qml index a3c3d4da..d507b796 100644 --- a/resources/qml/RoomDirectory.qml +++ b/resources/qml/RoomDirectory.qml @@ -1,195 +1,216 @@ -// SPDX-FileCopyrightText: 2021 Nheko Contributors -// -// SPDX-License-Identifier: GPL-3.0-or-later - -import "./ui" -import QtQuick 2.9 -import QtQuick.Controls 2.3 -import QtQuick.Layouts 1.3 -import im.nheko 1.0 - -ApplicationWindow { - id: roomDirectoryWindow - visible: true - - property RoomDirectoryModel publicRooms : RoomDirectoryModel {} - - x: MainWindow.x + (MainWindow.width / 2) - (width / 2) - y: MainWindow.y + (MainWindow.height / 2) - (height / 2) - minimumWidth: 650 - minimumHeight: 420 - palette: Nheko.colors - color: Nheko.colors.window - modality: Qt.WindowModal - flags: Qt.Dialog | Qt.WindowCloseButtonHint - title: qsTr("Explore Public Rooms") - - Shortcut { - sequence: StandardKey.Cancel - onActivated: roomDirectoryWindow.close() - } - - header: RowLayout { - id: searchBarLayout - spacing: Nheko.paddingMedium - width: parent.width - - implicitHeight: roomSearch.height - - MatrixTextField { - id: roomSearch - - Layout.fillWidth: true - selectByMouse: true - - font.pixelSize: fontMetrics.font.pixelSize - padding: Nheko.paddingMedium - color: Nheko.colors.text - placeholderText: qsTr("Search for public rooms") - onTextChanged: searchTimer.restart() - } - - Timer { - id: searchTimer - - interval: 350 - onTriggered: roomDirView.model.setSearchTerm(roomSearch.text) - } - } - - ListView { - id: roomDirView - anchors.fill: parent - model: publicRooms - delegate: Rectangle { - id: roomDirDelegate - - property color background: Nheko.colors.window - property color importantText: Nheko.colors.text - property color unimportantText: Nheko.colors.buttonText - property int avatarSize: fontMetrics.lineSpacing * 4 - - color: background - - height: avatarSize + 2.5 * Nheko.paddingMedium - width: ListView.view.width - - RowLayout { - - spacing: Nheko.paddingMedium - anchors.fill: parent - anchors.margins: Nheko.paddingMedium - implicitHeight: textContent.height - - Avatar { - id: roomAvatar - - Layout.alignment: Qt.AlignVCenter - width: avatarSize - height: avatarSize - url: model.avatarUrl.replace("mxc://", "image://MxcImage/") - displayName: model.name - } - - ColumnLayout { - id: textContent - - Layout.alignment: Qt.AlignLeft - Layout.fillWidth: true - width: parent.width - avatar.width - Layout.preferredWidth: parent.width - avatar.width - Layout.preferredHeight: roomNameRow.height + roomDescriptionRow.height - spacing: Nheko.paddingSmall - - RowLayout { - id: roomNameRow - Layout.fillWidth: true - spacing: 0 - - ElidedLabel { - Layout.alignment: Qt.AlignBottom - color: roomDirDelegate.importantText - elideWidth: textContent.width * 0.5 - Nheko.paddingMedium - font.pixelSize: fontMetrics.font.pixelSize * 1.1 - fullText: model.name - } - } - - RowLayout { - id: roomDescriptionRow - Layout.fillWidth: true - Layout.preferredWidth: parent.width - spacing: Nheko.paddingSmall - Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft - Layout.preferredHeight: fontMetrics.lineSpacing * 4 - - Label { - id: roomTopic - color: roomDirDelegate.unimportantText - font.weight: Font.Thin - Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft - font.pixelSize: fontMetrics.font.pixelSize - elide: Text.ElideRight - maximumLineCount: 2 - Layout.fillWidth: true - text: model.topic - verticalAlignment: Text.AlignVCenter - wrapMode: Text.WordWrap - } - Item { - id: numMembersRectangle - Layout.fillWidth: false - Layout.margins: Nheko.paddingSmall - width: roomCount.width - - Label { - id: roomCount - color: roomDirDelegate.unimportantText - anchors.centerIn: parent - Layout.fillWidth: false - font.weight: Font.Thin - font.pixelSize: fontMetrics.font.pixelSize - text: model.numMembers.toString() - } - } - - Item { - id: buttonRectangle - Layout.fillWidth: false - Layout.margins: Nheko.paddingSmall - width: joinRoomButton.width - Button { - id: joinRoomButton - visible: publicRooms.canJoinRoom(model.roomid) - anchors.centerIn: parent - width: Math.ceil(0.1 * roomDirectoryWindow.width) - text: "Join" - onClicked: publicRooms.joinRoom(model.index) - } - } - } - } - } - } - - footer: Item { - anchors.horizontalCenter: parent.horizontalCenter - width: parent.width - visible: (publicRooms.reachedEndOfPagination == false) && publicRooms.loadingMoreRooms - // hacky but works - height: loadingSpinner.height + 2 * Nheko.paddingLarge - anchors.margins: Nheko.paddingLarge - - Spinner { - id: loadingSpinner - - anchors.centerIn: parent - anchors.margins: Nheko.paddingLarge - running: visible - foreground: Nheko.colors.mid - z: 7 - } - } - - } -} +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +import "./ui" +import QtQuick 2.9 +import QtQuick.Controls 2.3 +import QtQuick.Layouts 1.3 +import im.nheko 1.0 + +ApplicationWindow { + id: roomDirectoryWindow + + property RoomDirectoryModel publicRooms + + visible: true + x: MainWindow.x + (MainWindow.width / 2) - (width / 2) + y: MainWindow.y + (MainWindow.height / 2) - (height / 2) + minimumWidth: 650 + minimumHeight: 420 + palette: Nheko.colors + color: Nheko.colors.window + modality: Qt.WindowModal + flags: Qt.Dialog | Qt.WindowCloseButtonHint + title: qsTr("Explore Public Rooms") + + Shortcut { + sequence: StandardKey.Cancel + onActivated: roomDirectoryWindow.close() + } + + ListView { + id: roomDirView + + anchors.fill: parent + model: publicRooms + + delegate: Rectangle { + id: roomDirDelegate + + property color background: Nheko.colors.window + property color importantText: Nheko.colors.text + property color unimportantText: Nheko.colors.buttonText + property int avatarSize: fontMetrics.lineSpacing * 4 + + color: background + height: avatarSize + 2.5 * Nheko.paddingMedium + width: ListView.view.width + + RowLayout { + spacing: Nheko.paddingMedium + anchors.fill: parent + anchors.margins: Nheko.paddingMedium + implicitHeight: textContent.height + + Avatar { + id: roomAvatar + + Layout.alignment: Qt.AlignVCenter + width: avatarSize + height: avatarSize + url: model.avatarUrl.replace("mxc://", "image://MxcImage/") + displayName: model.name + } + + ColumnLayout { + id: textContent + + Layout.alignment: Qt.AlignLeft + Layout.fillWidth: true + width: parent.width - avatar.width + Layout.preferredWidth: parent.width - avatar.width + Layout.preferredHeight: roomNameRow.height + roomDescriptionRow.height + spacing: Nheko.paddingSmall + + RowLayout { + id: roomNameRow + + Layout.fillWidth: true + spacing: 0 + + ElidedLabel { + Layout.alignment: Qt.AlignBottom + color: roomDirDelegate.importantText + elideWidth: textContent.width * 0.5 - Nheko.paddingMedium + font.pixelSize: fontMetrics.font.pixelSize * 1.1 + fullText: model.name + } + + } + + RowLayout { + id: roomDescriptionRow + + Layout.fillWidth: true + Layout.preferredWidth: parent.width + spacing: Nheko.paddingSmall + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + Layout.preferredHeight: fontMetrics.lineSpacing * 4 + + Label { + id: roomTopic + + color: roomDirDelegate.unimportantText + font.weight: Font.Thin + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + font.pixelSize: fontMetrics.font.pixelSize + elide: Text.ElideRight + maximumLineCount: 2 + Layout.fillWidth: true + text: model.topic + verticalAlignment: Text.AlignVCenter + wrapMode: Text.WordWrap + } + + Item { + id: numMembersRectangle + + Layout.fillWidth: false + Layout.margins: Nheko.paddingSmall + width: roomCount.width + + Label { + id: roomCount + + color: roomDirDelegate.unimportantText + anchors.centerIn: parent + Layout.fillWidth: false + font.weight: Font.Thin + font.pixelSize: fontMetrics.font.pixelSize + text: model.numMembers.toString() + } + + } + + Item { + id: buttonRectangle + + Layout.fillWidth: false + Layout.margins: Nheko.paddingSmall + width: joinRoomButton.width + + Button { + id: joinRoomButton + + visible: publicRooms.canJoinRoom(model.roomid) + anchors.centerIn: parent + width: Math.ceil(0.1 * roomDirectoryWindow.width) + text: "Join" + onClicked: publicRooms.joinRoom(model.index) + } + + } + + } + + } + + } + + } + + footer: Item { + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width + visible: (publicRooms.reachedEndOfPagination == false) && publicRooms.loadingMoreRooms + // hacky but works + height: loadingSpinner.height + 2 * Nheko.paddingLarge + anchors.margins: Nheko.paddingLarge + + Spinner { + id: loadingSpinner + + anchors.centerIn: parent + anchors.margins: Nheko.paddingLarge + running: visible + foreground: Nheko.colors.mid + z: 7 + } + + } + + } + + publicRooms: RoomDirectoryModel { + } + + header: RowLayout { + id: searchBarLayout + + spacing: Nheko.paddingMedium + width: parent.width + implicitHeight: roomSearch.height + + MatrixTextField { + id: roomSearch + + Layout.fillWidth: true + selectByMouse: true + font.pixelSize: fontMetrics.font.pixelSize + padding: Nheko.paddingMedium + color: Nheko.colors.text + placeholderText: qsTr("Search for public rooms") + onTextChanged: searchTimer.restart() + } + + Timer { + id: searchTimer + + interval: 350 + onTriggered: roomDirView.model.setSearchTerm(roomSearch.text) + } + + } + +} diff --git a/src/RoomDirectoryModel.cpp b/src/RoomDirectoryModel.cpp index 7d6be13e..5873771f 100644 --- a/src/RoomDirectoryModel.cpp +++ b/src/RoomDirectoryModel.cpp @@ -82,10 +82,10 @@ RoomDirectoryModel::getViasForRoom(const std::vector &aliases) vias.reserve(aliases.size()); - std::transform( - aliases.begin(), aliases.end(), std::back_inserter(vias), [](const auto &alias) { - return alias.substr(alias.find(":") + 1); - }); + std::transform(aliases.begin(), + aliases.end(), + std::back_inserter(vias), + [](const auto &alias) { return alias.substr(alias.find(":") + 1); }); return vias; } @@ -126,7 +126,8 @@ RoomDirectoryModel::data(const QModelIndex &index, int role) const void RoomDirectoryModel::fetchMore(const QModelIndex &) { - if (!canFetchMore_) return; + if (!canFetchMore_) + return; nhlog::net()->debug("Fetching more rooms from mtxclient..."); @@ -137,18 +138,18 @@ RoomDirectoryModel::fetchMore(const QModelIndex &) // req.third_party_instance_id = third_party_instance_id; auto requested_server = server_; - reachedEndOfPagination_ = false; - emit reachedEndOfPaginationChanged(); + reachedEndOfPagination_ = false; + emit reachedEndOfPaginationChanged(); - loadingMoreRooms_ = true; - emit loadingMoreRoomsChanged(); + 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(); + loadingMoreRooms_ = false; + emit loadingMoreRoomsChanged(); if (err) { nhlog::net()->error( @@ -184,12 +185,12 @@ RoomDirectoryModel::displayRooms(std::vector f endInsertRows(); if (next_batch.empty()) { - canFetchMore_ = false; - reachedEndOfPagination_ = true; - emit reachedEndOfPaginationChanged(); + canFetchMore_ = false; + reachedEndOfPagination_ = true; + emit reachedEndOfPaginationChanged(); } prevBatch_ = next_batch; - nhlog::ui()->debug ("Finished loading rooms"); + nhlog::ui()->debug("Finished loading rooms"); } diff --git a/src/RoomDirectoryModel.h b/src/RoomDirectoryModel.h index a7e6c0bc..b7eda00d 100644 --- a/src/RoomDirectoryModel.h +++ b/src/RoomDirectoryModel.h @@ -27,8 +27,9 @@ class RoomDirectoryModel : public QAbstractListModel { Q_OBJECT - Q_PROPERTY (bool loadingMoreRooms READ loadingMoreRooms NOTIFY loadingMoreRoomsChanged) - Q_PROPERTY (bool reachedEndOfPagination READ reachedEndOfPagination NOTIFY reachedEndOfPaginationChanged) + 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 &s = ""); @@ -52,14 +53,11 @@ public: return static_cast(publicRoomsData_.size()); } - bool canFetchMore(const QModelIndex &) const override - { - return canFetchMore_; - } + bool canFetchMore(const QModelIndex &) const override { return canFetchMore_; } - bool loadingMoreRooms() const { return loadingMoreRooms_; } + bool loadingMoreRooms() const { return loadingMoreRooms_; } - bool reachedEndOfPagination() const { return reachedEndOfPagination_; } + bool reachedEndOfPagination() const { return reachedEndOfPagination_; } void fetchMore(const QModelIndex &) override; @@ -69,8 +67,8 @@ public: signals: void fetchedRoomsBatch(std::vector rooms, const std::string &next_batch); - void loadingMoreRoomsChanged(); - void reachedEndOfPaginationChanged(); + void loadingMoreRoomsChanged(); + void reachedEndOfPaginationChanged(); public slots: void displayRooms(std::vector rooms, @@ -85,9 +83,9 @@ private: std::string userSearchString_; std::string prevBatch_; std::string nextBatch_; - bool canFetchMore_ {true}; - bool loadingMoreRooms_ {false}; - bool reachedEndOfPagination_ {false}; + bool canFetchMore_{true}; + bool loadingMoreRooms_{false}; + bool reachedEndOfPagination_{false}; std::vector publicRoomsData_; std::vector getViasForRoom(const std::vector &room); diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index ff60856a..6f935760 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -286,8 +286,7 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par "EmojiCategory", "Error: Only enums"); - qmlRegisterType( - "im.nheko", 1, 0, "RoomDirectoryModel"); + qmlRegisterType("im.nheko", 1, 0, "RoomDirectoryModel"); #ifdef USE_QUICK_VIEW view = new QQuickView(parent); From eaddfb4f7308a3ae4a84c11fff279d9b872932ef Mon Sep 17 00:00:00 2001 From: kamathmanu Date: Sat, 14 Aug 2021 09:44:34 -0400 Subject: [PATCH 14/17] Clean up final nits --- resources/qml/RoomDirectory.qml | 17 ++++++++--------- src/RoomDirectoryModel.cpp | 4 +--- src/RoomDirectoryModel.h | 7 +++++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/resources/qml/RoomDirectory.qml b/resources/qml/RoomDirectory.qml index d507b796..abd35c57 100644 --- a/resources/qml/RoomDirectory.qml +++ b/resources/qml/RoomDirectory.qml @@ -22,6 +22,7 @@ ApplicationWindow { color: Nheko.colors.window modality: Qt.WindowModal flags: Qt.Dialog | Qt.WindowCloseButtonHint + Component.onCompleted: Nheko.reparent(roomDirectoryWindow) title: qsTr("Explore Public Rooms") Shortcut { @@ -35,6 +36,12 @@ ApplicationWindow { anchors.fill: parent model: publicRooms + ScrollHelper { + flickable: parent + anchors.fill: parent + enabled: !Settings.mobileMode + } + delegate: Rectangle { id: roomDirDelegate @@ -44,7 +51,7 @@ ApplicationWindow { property int avatarSize: fontMetrics.lineSpacing * 4 color: background - height: avatarSize + 2.5 * Nheko.paddingMedium + height: avatarSize + Nheko.paddingLarge width: ListView.view.width RowLayout { @@ -67,7 +74,6 @@ ApplicationWindow { id: textContent Layout.alignment: Qt.AlignLeft - Layout.fillWidth: true width: parent.width - avatar.width Layout.preferredWidth: parent.width - avatar.width Layout.preferredHeight: roomNameRow.height + roomDescriptionRow.height @@ -76,7 +82,6 @@ ApplicationWindow { RowLayout { id: roomNameRow - Layout.fillWidth: true spacing: 0 ElidedLabel { @@ -92,7 +97,6 @@ ApplicationWindow { RowLayout { id: roomDescriptionRow - Layout.fillWidth: true Layout.preferredWidth: parent.width spacing: Nheko.paddingSmall Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft @@ -116,7 +120,6 @@ ApplicationWindow { Item { id: numMembersRectangle - Layout.fillWidth: false Layout.margins: Nheko.paddingSmall width: roomCount.width @@ -125,8 +128,6 @@ ApplicationWindow { color: roomDirDelegate.unimportantText anchors.centerIn: parent - Layout.fillWidth: false - font.weight: Font.Thin font.pixelSize: fontMetrics.font.pixelSize text: model.numMembers.toString() } @@ -136,7 +137,6 @@ ApplicationWindow { Item { id: buttonRectangle - Layout.fillWidth: false Layout.margins: Nheko.paddingSmall width: joinRoomButton.width @@ -175,7 +175,6 @@ ApplicationWindow { anchors.margins: Nheko.paddingLarge running: visible foreground: Nheko.colors.mid - z: 7 } } diff --git a/src/RoomDirectoryModel.cpp b/src/RoomDirectoryModel.cpp index 5873771f..61c3eb72 100644 --- a/src/RoomDirectoryModel.cpp +++ b/src/RoomDirectoryModel.cpp @@ -69,10 +69,8 @@ RoomDirectoryModel::setSearchTerm(const QString &f) bool RoomDirectoryModel::canJoinRoom(const QByteArray &room) { - 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); + return !room_id.isEmpty() && !cache::getRoomInfo({room_id.toStdString()}).count(room_id); } std::vector diff --git a/src/RoomDirectoryModel.h b/src/RoomDirectoryModel.h index b7eda00d..791384fa 100644 --- a/src/RoomDirectoryModel.h +++ b/src/RoomDirectoryModel.h @@ -71,11 +71,14 @@ signals: void reachedEndOfPaginationChanged(); public slots: - void displayRooms(std::vector rooms, - const std::string &next_batch); void setMatrixServer(const QString &s = ""); void setSearchTerm(const QString &f); +private slots: + + void displayRooms(std::vector rooms, + const std::string &next_batch); + private: static constexpr size_t limit_ = 50; From 0f4a7b1ba63a50f6b5603cb94e686d7fe230371e Mon Sep 17 00:00:00 2001 From: kamathmanu Date: Sat, 14 Aug 2021 09:49:18 -0400 Subject: [PATCH 15/17] Formatting + Licensing --- resources/qml/RoomDirectory.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/RoomDirectory.qml b/resources/qml/RoomDirectory.qml index abd35c57..cd409bea 100644 --- a/resources/qml/RoomDirectory.qml +++ b/resources/qml/RoomDirectory.qml @@ -36,7 +36,7 @@ ApplicationWindow { anchors.fill: parent model: publicRooms - ScrollHelper { + ScrollHelper { flickable: parent anchors.fill: parent enabled: !Settings.mobileMode From 7321af8a7d9cf01317b0a46c36eab25f2e95f5a8 Mon Sep 17 00:00:00 2001 From: kamathmanu Date: Sat, 14 Aug 2021 21:47:11 -0400 Subject: [PATCH 16/17] Cleanup more nits --- resources/qml/RoomDirectory.qml | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/resources/qml/RoomDirectory.qml b/resources/qml/RoomDirectory.qml index cd409bea..129391a5 100644 --- a/resources/qml/RoomDirectory.qml +++ b/resources/qml/RoomDirectory.qml @@ -14,8 +14,6 @@ ApplicationWindow { property RoomDirectoryModel publicRooms visible: true - x: MainWindow.x + (MainWindow.width / 2) - (width / 2) - y: MainWindow.y + (MainWindow.height / 2) - (height / 2) minimumWidth: 650 minimumHeight: 420 palette: Nheko.colors @@ -57,7 +55,7 @@ ApplicationWindow { RowLayout { spacing: Nheko.paddingMedium anchors.fill: parent - anchors.margins: Nheko.paddingMedium + anchors.margins: Nheko.paddingLarge implicitHeight: textContent.height Avatar { @@ -76,22 +74,14 @@ ApplicationWindow { Layout.alignment: Qt.AlignLeft width: parent.width - avatar.width Layout.preferredWidth: parent.width - avatar.width - Layout.preferredHeight: roomNameRow.height + roomDescriptionRow.height spacing: Nheko.paddingSmall - RowLayout { - id: roomNameRow - - spacing: 0 - - ElidedLabel { - Layout.alignment: Qt.AlignBottom - color: roomDirDelegate.importantText - elideWidth: textContent.width * 0.5 - Nheko.paddingMedium - font.pixelSize: fontMetrics.font.pixelSize * 1.1 - fullText: model.name - } - + ElidedLabel { + Layout.alignment: Qt.AlignBottom + color: roomDirDelegate.importantText + elideWidth: textContent.width - numMembersRectangle.width - buttonRectangle.width + font.pixelSize: fontMetrics.font.pixelSize * 1.1 + fullText: model.name } RowLayout { @@ -106,7 +96,6 @@ ApplicationWindow { id: roomTopic color: roomDirDelegate.unimportantText - font.weight: Font.Thin Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft font.pixelSize: fontMetrics.font.pixelSize elide: Text.ElideRight @@ -163,7 +152,7 @@ ApplicationWindow { footer: Item { anchors.horizontalCenter: parent.horizontalCenter width: parent.width - visible: (publicRooms.reachedEndOfPagination == false) && publicRooms.loadingMoreRooms + visible: !publicRooms.reachedEndOfPagination && publicRooms.loadingMoreRooms // hacky but works height: loadingSpinner.height + 2 * Nheko.paddingLarge anchors.margins: Nheko.paddingLarge From 820665db92f1f400c6f0d118d3aed36f557dde6c Mon Sep 17 00:00:00 2001 From: kamathmanu Date: Sat, 14 Aug 2021 21:58:56 -0400 Subject: [PATCH 17/17] Formatting --- resources/qml/RoomDirectory.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/RoomDirectory.qml b/resources/qml/RoomDirectory.qml index 129391a5..4db24f01 100644 --- a/resources/qml/RoomDirectory.qml +++ b/resources/qml/RoomDirectory.qml @@ -79,7 +79,7 @@ ApplicationWindow { ElidedLabel { Layout.alignment: Qt.AlignBottom color: roomDirDelegate.importantText - elideWidth: textContent.width - numMembersRectangle.width - buttonRectangle.width + elideWidth: textContent.width - numMembersRectangle.width - buttonRectangle.width font.pixelSize: fontMetrics.font.pixelSize * 1.1 fullText: model.name }