summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChatPage.cc80
-rw-r--r--src/CommunitiesList.cc150
-rw-r--r--src/CommunitiesListItem.cc200
-rw-r--r--src/Community.cc44
-rw-r--r--src/MatrixClient.cc148
-rw-r--r--src/RoomInfoListItem.cc5
-rw-r--r--src/RoomList.cc53
7 files changed, 673 insertions, 7 deletions
diff --git a/src/ChatPage.cc b/src/ChatPage.cc

index 3958e2c2..3a78e1cc 100644 --- a/src/ChatPage.cc +++ b/src/ChatPage.cc
@@ -60,6 +60,17 @@ ChatPage::ChatPage(QSharedPointer<MatrixClient> client, topLayout_->setSpacing(0); topLayout_->setMargin(0); + communitiesSideBar_ = new QWidget(this); + communitiesSideBar_->setFixedWidth(ui::sidebar::CommunitiesSidebarSize); + communitiesSideBarLayout_ = new QVBoxLayout(communitiesSideBar_); + communitiesSideBarLayout_->setSpacing(0); + communitiesSideBarLayout_->setMargin(0); + + communitiesList_ = new CommunitiesList(client, this); + communitiesSideBarLayout_->addWidget(communitiesList_); + // communitiesSideBarLayout_->addStretch(1); + topLayout_->addWidget(communitiesSideBar_); + auto splitter = new Splitter(this); splitter->setHandleWidth(0); @@ -72,7 +83,18 @@ ChatPage::ChatPage(QSharedPointer<MatrixClient> client, sideBarLayout_->setSpacing(0); sideBarLayout_->setMargin(0); - sidebarActions_ = new SideBarActions(this); + sideBarTopLayout_ = new QVBoxLayout(); + sideBarTopLayout_->setSpacing(0); + sideBarTopLayout_->setMargin(0); + sideBarMainLayout_ = new QVBoxLayout(); + sideBarMainLayout_->setSpacing(0); + sideBarMainLayout_->setMargin(0); + + sideBarLayout_->addLayout(sideBarTopLayout_); + sideBarLayout_->addLayout(sideBarMainLayout_); + + sideBarTopWidget_ = new QWidget(sideBar_); + sidebarActions_ = new SideBarActions(this); connect( sidebarActions_, &SideBarActions::showSettings, this, &ChatPage::showUserSettingsPage); connect( @@ -87,6 +109,10 @@ ChatPage::ChatPage(QSharedPointer<MatrixClient> client, sideBarLayout_->addWidget(room_list_); sideBarLayout_->addWidget(sidebarActions_); + sideBarTopWidgetLayout_ = new QVBoxLayout(sideBarTopWidget_); + sideBarTopWidgetLayout_->setSpacing(0); + sideBarTopWidgetLayout_->setMargin(0); + // Content content_ = new QFrame(this); content_->setObjectName("mainContent"); @@ -274,6 +300,32 @@ ChatPage::ChatPage(QSharedPointer<MatrixClient> client, &MatrixClient::getOwnProfileResponse, this, &ChatPage::updateOwnProfileInfo); + connect(client_.data(), + SIGNAL(getOwnCommunitiesResponse(QList<QString>)), + this, + SLOT(updateOwnCommunitiesInfo(QList<QString>))); + connect(client_.data(), + &MatrixClient::communityProfileRetrieved, + this, + [=](QString communityId, QJsonObject profile) { + communityManager_[communityId]->parseProfile(profile); + }); + connect(client_.data(), + &MatrixClient::communityRoomsRetrieved, + this, + [=](QString communityId, QJsonObject rooms) { + communityManager_[communityId]->parseRooms(rooms); + + if (communityId == current_community_) { + if (communityId == "world") { + room_list_->setFilterRooms(false); + } else { + room_list_->setRoomFilter( + communityManager_[communityId]->getRoomList()); + } + } + }); + connect(client_.data(), &MatrixClient::ownAvatarRetrieved, this, &ChatPage::setOwnAvatar); connect(client_.data(), &MatrixClient::joinedRoom, this, [=](const QString &room_id) { emit showNotification("You joined the room."); @@ -304,6 +356,19 @@ ChatPage::ChatPage(QSharedPointer<MatrixClient> client, } }); + connect(communitiesList_, + &CommunitiesList::communityChanged, + this, + [=](const QString &communityId) { + current_community_ = communityId; + if (communityId == "world") { + room_list_->setFilterRooms(false); + } else { + room_list_->setRoomFilter( + communityManager_[communityId]->getRoomList()); + } + }); + AvatarProvider::init(client); instance_ = this; @@ -359,6 +424,7 @@ ChatPage::bootstrap(QString userid, QString homeserver, QString token) client_->setServer(homeserver); client_->setAccessToken(token); client_->getOwnProfile(); + client_->getOwnCommunities(); cache_ = QSharedPointer<Cache>(new Cache(userid)); room_list_->setCache(cache_); @@ -501,6 +567,18 @@ ChatPage::updateOwnProfileInfo(const QUrl &avatar_url, const QString &display_na } void +ChatPage::updateOwnCommunitiesInfo(const QList<QString> &own_communities) +{ + for (int i = 0; i < own_communities.size(); i++) { + QSharedPointer<Community> community = QSharedPointer<Community>(new Community()); + + communityManager_[own_communities[i]] = community; + } + + communitiesList_->setCommunities(communityManager_); +} + +void ChatPage::changeTopRoomInfo(const QString &room_id) { if (!state_manager_.contains(room_id)) diff --git a/src/CommunitiesList.cc b/src/CommunitiesList.cc new file mode 100644
index 00000000..c40155e5 --- /dev/null +++ b/src/CommunitiesList.cc
@@ -0,0 +1,150 @@ +#include "CommunitiesList.h" + +#include <QLabel> + +CommunitiesList::CommunitiesList(QSharedPointer<MatrixClient> client, QWidget *parent) + : QWidget(parent) + , client_(client) +{ + QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(1); + setSizePolicy(sizePolicy); + + setStyleSheet("border-style: none;"); + + topLayout_ = new QVBoxLayout(this); + topLayout_->setSpacing(0); + topLayout_->setMargin(0); + + setFixedWidth(ui::sidebar::CommunitiesSidebarSize); + + scrollArea_ = new QScrollArea(this); + scrollArea_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + scrollArea_->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + scrollArea_->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents); + scrollArea_->setWidgetResizable(true); + scrollArea_->setAlignment(Qt::AlignLeading | Qt::AlignTop | Qt::AlignVCenter); + + scrollAreaContents_ = new QWidget(); + + contentsLayout_ = new QVBoxLayout(scrollAreaContents_); + contentsLayout_->setSpacing(0); + contentsLayout_->setMargin(0); + + WorldCommunityListItem *world_list_item = new WorldCommunityListItem(); + contentsLayout_->addWidget(world_list_item); + communities_.insert("world", QSharedPointer<CommunitiesListItem>(world_list_item)); + connect(world_list_item, + &WorldCommunityListItem::clicked, + this, + &CommunitiesList::highlightSelectedCommunity); + contentsLayout_->addStretch(1); + + scrollArea_->setWidget(scrollAreaContents_); + topLayout_->addWidget(scrollArea_); + + connect(client_.data(), + &MatrixClient::communityProfileRetrieved, + this, + [=](QString communityId, QJsonObject profile) { + client_->fetchCommunityAvatar(communityId, + QUrl(profile["avatar_url"].toString())); + }); + connect(client_.data(), + SIGNAL(communityAvatarRetrieved(const QString &, const QPixmap &)), + this, + SLOT(updateCommunityAvatar(const QString &, const QPixmap &))); +} + +CommunitiesList::~CommunitiesList() {} + +void +CommunitiesList::setCommunities(const QMap<QString, QSharedPointer<Community>> &communities) +{ + communities_.clear(); + + // TODO: still not sure how to handle the "world" special-case + WorldCommunityListItem *world_list_item = new WorldCommunityListItem(); + communities_.insert("world", QSharedPointer<CommunitiesListItem>(world_list_item)); + connect(world_list_item, + &WorldCommunityListItem::clicked, + this, + &CommunitiesList::highlightSelectedCommunity); + contentsLayout_->insertWidget(0, world_list_item); + + for (auto it = communities.constBegin(); it != communities.constEnd(); it++) { + const auto community_id = it.key(); + const auto community = it.value(); + + addCommunity(community, community_id); + + client_->fetchCommunityProfile(community_id); + client_->fetchCommunityRooms(community_id); + } + + world_list_item->setPressedState(true); + emit communityChanged("world"); +} + +void +CommunitiesList::clear() +{ + communities_.clear(); +} + +void +CommunitiesList::addCommunity(QSharedPointer<Community> community, const QString &community_id) +{ + CommunitiesListItem *list_item = + new CommunitiesListItem(community, community_id, scrollArea_); + + communities_.insert(community_id, QSharedPointer<CommunitiesListItem>(list_item)); + + client_->fetchCommunityAvatar(community_id, community->getAvatar()); + + contentsLayout_->insertWidget(contentsLayout_->count() - 1, list_item); + + connect(list_item, + &CommunitiesListItem::clicked, + this, + &CommunitiesList::highlightSelectedCommunity); +} + +void +CommunitiesList::removeCommunity(const QString &community_id) +{ + communities_.remove(community_id); +} + +void +CommunitiesList::updateCommunityAvatar(const QString &community_id, const QPixmap &img) +{ + if (!communities_.contains(community_id)) { + qWarning() << "Avatar update on nonexistent community" << community_id; + return; + } + + communities_.value(community_id)->setAvatar(img.toImage()); +} + +void +CommunitiesList::highlightSelectedCommunity(const QString &community_id) +{ + emit communityChanged(community_id); + + if (!communities_.contains(community_id)) { + qDebug() << "CommunitiesList: clicked unknown community"; + return; + } + + for (auto it = communities_.constBegin(); it != communities_.constEnd(); it++) { + if (it.key() != community_id) { + it.value()->setPressedState(false); + } else { + it.value()->setPressedState(true); + scrollArea_->ensureWidgetVisible( + qobject_cast<QWidget *>(it.value().data())); + } + } +} diff --git a/src/CommunitiesListItem.cc b/src/CommunitiesListItem.cc new file mode 100644
index 00000000..a7789df7 --- /dev/null +++ b/src/CommunitiesListItem.cc
@@ -0,0 +1,200 @@ +#include "CommunitiesListItem.h" + +CommunitiesListItem::CommunitiesListItem(QSharedPointer<Community> community, + QString community_id, + QWidget *parent) + : QWidget(parent) + , community_(community) + , communityId_(community_id) +{ + // menu_ = new Menu(this); + setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + setFixedHeight(ui::sidebar::CommunitiesSidebarSize); + setFixedWidth(ui::sidebar::CommunitiesSidebarSize); +} + +CommunitiesListItem::~CommunitiesListItem() {} + +void +CommunitiesListItem::setCommunity(QSharedPointer<Community> community) +{ + community_ = community; +} + +void +CommunitiesListItem::setPressedState(bool state) +{ + if (isPressed_ != state) { + isPressed_ = state; + update(); + } +} + +void +CommunitiesListItem::mousePressEvent(QMouseEvent *event) +{ + if (event->buttons() == Qt::RightButton) { + QWidget::mousePressEvent(event); + return; + } + + emit clicked(communityId_); + + setPressedState(true); +} + +void +CommunitiesListItem::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event); + + QPainter p(this); + p.setRenderHint(QPainter::TextAntialiasing); + p.setRenderHint(QPainter::SmoothPixmapTransform); + p.setRenderHint(QPainter::Antialiasing); + + if (isPressed_) + p.fillRect(rect(), highlightedBackgroundColor_); + else if (underMouse()) + p.fillRect(rect(), hoverBackgroundColor_); + else + p.fillRect(rect(), backgroundColor_); + + QFont font; + font.setPixelSize(conf::fontSize); + + p.setPen(QColor("#333")); + + QRect avatarRegion((width() - IconSize) / 2, (height() - IconSize) / 2, IconSize, IconSize); + + font.setBold(false); + p.setPen(Qt::NoPen); + + // We using the first letter of room's name. + if (communityAvatar_.isNull()) { + QBrush brush; + brush.setStyle(Qt::SolidPattern); + brush.setColor("#eee"); + + p.setPen(Qt::NoPen); + p.setBrush(brush); + + p.drawEllipse(avatarRegion.center(), IconSize / 2, IconSize / 2); + + font.setPixelSize(conf::roomlist::fonts::bubble); + p.setFont(font); + p.setPen(QColor("#000")); + p.setBrush(Qt::NoBrush); + p.drawText( + avatarRegion.translated(0, -1), Qt::AlignCenter, QChar(community_->getName()[0])); + } else { + p.save(); + + QPainterPath path; + path.addEllipse( + (width() - IconSize) / 2, (height() - IconSize) / 2, IconSize, IconSize); + p.setClipPath(path); + + p.drawPixmap(avatarRegion, communityAvatar_); + p.restore(); + } + + // TODO: Discord-style community ping counts? + /*if (unreadMsgCount_ > 0) { + QColor textColor("white"); + QColor backgroundColor("#38A3D8"); + + QBrush brush; + brush.setStyle(Qt::SolidPattern); + brush.setColor(backgroundColor); + + if (isPressed_) + brush.setColor(textColor); + + QFont unreadCountFont; + unreadCountFont.setPixelSize(conf::roomlist::fonts::badge); + unreadCountFont.setBold(true); + + p.setBrush(brush); + p.setPen(Qt::NoPen); + p.setFont(unreadCountFont); + + int diameter = 20; + + QRectF r( + width() - diameter - 5, height() - diameter - 5, diameter, diameter); + + p.setPen(Qt::NoPen); + p.drawEllipse(r); + + p.setPen(QPen(textColor)); + + if (isPressed_) + p.setPen(QPen(backgroundColor)); + + p.setBrush(Qt::NoBrush); + p.drawText( + r.translated(0, -0.5), Qt::AlignCenter, QString::number(unreadMsgCount_)); + }*/ +} + +void +CommunitiesListItem::contextMenuEvent(QContextMenuEvent *event) +{ + Q_UNUSED(event); + + // menu_->popup(event->globalPos()); +} + +WorldCommunityListItem::WorldCommunityListItem(QWidget *parent) + : CommunitiesListItem(QSharedPointer<Community>(), "", parent) +{} + +WorldCommunityListItem::~WorldCommunityListItem() {} + +void +WorldCommunityListItem::mousePressEvent(QMouseEvent *event) +{ + if (event->buttons() == Qt::RightButton) { + QWidget::mousePressEvent(event); + return; + } + + emit CommunitiesListItem::clicked("world"); + + setPressedState(true); +} + +void +WorldCommunityListItem::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event); + + static QPixmap worldIcon(":/icons/icons/ui/world.png"); + + QPainter p(this); + p.setRenderHint(QPainter::SmoothPixmapTransform); + p.setRenderHint(QPainter::Antialiasing); + + if (isPressed()) + p.fillRect(rect(), highlightedBackgroundColor_); + else if (underMouse()) + p.fillRect(rect(), hoverBackgroundColor_); + else + p.fillRect(rect(), backgroundColor_); + + QBrush brush; + brush.setStyle(Qt::SolidPattern); + brush.setColor("#FFFFFF"); + + p.setPen(Qt::NoPen); + p.setBrush(brush); + + QRect avatarRegion((width() - IconSize) / 2, (height() - IconSize) / 2, IconSize, IconSize); + p.drawEllipse(avatarRegion.center(), IconSize / 2, IconSize / 2); + QPainterPath path; + path.addEllipse((width() - IconSize) / 2, (height() - IconSize) / 2, IconSize, IconSize); + p.setClipPath(path); + + p.drawPixmap(avatarRegion, worldIcon); +} diff --git a/src/Community.cc b/src/Community.cc new file mode 100644
index 00000000..df425e88 --- /dev/null +++ b/src/Community.cc
@@ -0,0 +1,44 @@ +#include "include/Community.h" + +#include <QJsonArray> +#include <QJsonValue> + +void +Community::parseProfile(const QJsonObject &profile) +{ + if (profile["name"].type() == QJsonValue::Type::String) { + name_ = profile["name"].toString(); + } else { + name_ = "Unnamed Community"; // TODO: what is correct here? + } + + if (profile["avatar_url"].type() == QJsonValue::Type::String) { + avatar_ = QUrl(profile["avatar_url"].toString()); + } else { + avatar_ = QUrl(); + } + + if (profile["short_description"].type() == QJsonValue::Type::String) { + short_description_ = profile["short_description"].toString(); + } else { + short_description_ = ""; + } + + if (profile["long_description"].type() == QJsonValue::Type::String) { + long_description_ = profile["long_description"].toString(); + } else { + long_description_ = ""; + } +} + +void +Community::parseRooms(const QJsonObject &rooms) +{ + rooms_.clear(); + + for (auto i = 0; i < rooms["chunk"].toArray().size(); i++) { + rooms_.append(rooms["chunk"].toArray()[i].toObject()["room_id"].toString()); + } + + emit roomsChanged(rooms_); +} diff --git a/src/MatrixClient.cc b/src/MatrixClient.cc
index 1b2e020d..72467385 100644 --- a/src/MatrixClient.cc +++ b/src/MatrixClient.cc
@@ -112,7 +112,6 @@ MatrixClient::login(const QString &username, const QString &password) noexcept } }); } - void MatrixClient::logout() noexcept { @@ -445,6 +444,46 @@ MatrixClient::getOwnProfile() noexcept } void +MatrixClient::getOwnCommunities() noexcept +{ + QUrlQuery query; + query.addQueryItem("access_token", token_); + + QUrl endpoint(server_); + endpoint.setPath(clientApiUrl_ + "/joined_groups"); + endpoint.setQuery(query); + + QNetworkRequest request(QString(endpoint.toEncoded())); + + QNetworkReply *reply = get(request); + connect(reply, &QNetworkReply::finished, this, [this, reply]() { + reply->deleteLater(); + + int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + + if (status >= 400) { + qWarning() << reply->errorString(); + return; + } + + auto data = reply->readAll(); + auto json = QJsonDocument::fromJson(data).object(); + + try { + QList<QString> response; + for (auto it = json["groups"].toArray().constBegin(); + it != json["groups"].toArray().constEnd(); + it++) { + response.append(it->toString()); + } + emit getOwnCommunitiesResponse(response); + } catch (DeserializationException &e) { + qWarning() << "Own communities:" << e.what(); + } + }); +} + +void MatrixClient::fetchRoomAvatar(const QString &roomid, const QUrl &avatar_url) { QList<QString> url_parts = avatar_url.toString().split("mxc://"); @@ -491,6 +530,113 @@ MatrixClient::fetchRoomAvatar(const QString &roomid, const QUrl &avatar_url) } void +MatrixClient::fetchCommunityAvatar(const QString &communityId, const QUrl &avatar_url) +{ + QList<QString> url_parts = avatar_url.toString().split("mxc://"); + + if (url_parts.size() != 2) { + qDebug() << "Invalid format for community avatar " << avatar_url.toString(); + return; + } + + QUrlQuery query; + query.addQueryItem("width", "512"); + query.addQueryItem("height", "512"); + query.addQueryItem("method", "crop"); + + QString media_url = + QString("%1/_matrix/media/r0/thumbnail/%2").arg(getHomeServer().toString(), url_parts[1]); + + QUrl endpoint(media_url); + endpoint.setQuery(query); + + QNetworkRequest avatar_request(endpoint); + + QNetworkReply *reply = get(avatar_request); + connect(reply, &QNetworkReply::finished, this, [this, reply, communityId]() { + reply->deleteLater(); + + int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + + if (status == 0 || status >= 400) { + qWarning() << reply->errorString(); + return; + } + + auto img = reply->readAll(); + + if (img.size() == 0) + return; + + QPixmap pixmap; + pixmap.loadFromData(img); + + emit communityAvatarRetrieved(communityId, pixmap); + }); +} + +void +MatrixClient::fetchCommunityProfile(const QString &communityId) +{ + QUrlQuery query; + query.addQueryItem("access_token", token_); + + QUrl endpoint(server_); + endpoint.setPath(clientApiUrl_ + "/groups/" + communityId + "/profile"); + endpoint.setQuery(query); + + QNetworkRequest request(QString(endpoint.toEncoded())); + + QNetworkReply *reply = get(request); + + connect(reply, &QNetworkReply::finished, this, [this, reply, communityId]() { + reply->deleteLater(); + + int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + + if (status >= 400) { + qWarning() << reply->errorString(); + return; + } + + auto data = reply->readAll(); + const auto json = QJsonDocument::fromJson(data).object(); + + emit communityProfileRetrieved(communityId, json); + }); +} + +void +MatrixClient::fetchCommunityRooms(const QString &communityId) +{ + QUrlQuery query; + query.addQueryItem("access_token", token_); + + QUrl endpoint(server_); + endpoint.setPath(clientApiUrl_ + "/groups/" + communityId + "/rooms"); + endpoint.setQuery(query); + + QNetworkRequest request(QString(endpoint.toEncoded())); + + QNetworkReply *reply = get(request); + connect(reply, &QNetworkReply::finished, this, [this, reply, communityId]() { + reply->deleteLater(); + + int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + + if (status >= 400) { + qWarning() << reply->errorString(); + return; + } + + auto data = reply->readAll(); + const auto json = QJsonDocument::fromJson(data).object(); + + emit communityRoomsRetrieved(communityId, json); + }); +} + +void MatrixClient::fetchUserAvatar(const QString &userId, const QUrl &avatarUrl) { QList<QString> url_parts = avatarUrl.toString().split("mxc://"); diff --git a/src/RoomInfoListItem.cc b/src/RoomInfoListItem.cc
index 551895d6..f8989948 100644 --- a/src/RoomInfoListItem.cc +++ b/src/RoomInfoListItem.cc
@@ -315,10 +315,7 @@ RoomInfoListItem::clearUnreadMessageCount() void RoomInfoListItem::setPressedState(bool state) { - if (!isPressed_ && state) { - isPressed_ = state; - update(); - } else if (isPressed_ && !state) { + if (isPressed_ != state) { isPressed_ = state; update(); } diff --git a/src/RoomList.cc b/src/RoomList.cc
index 0274cefe..30be6cf6 100644 --- a/src/RoomList.cc +++ b/src/RoomList.cc
@@ -47,7 +47,7 @@ RoomList::RoomList(QSharedPointer<MatrixClient> client, scrollArea_->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); scrollArea_->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents); scrollArea_->setWidgetResizable(true); - scrollArea_->setAlignment(Qt::AlignLeading | Qt::AlignLeft | Qt::AlignVCenter); + scrollArea_->setAlignment(Qt::AlignLeading | Qt::AlignTop | Qt::AlignVCenter); scrollAreaContents_ = new QWidget(this); @@ -181,6 +181,8 @@ RoomList::setInitialRooms(const QMap<QString, QSharedPointer<RoomSettings>> &set if (rooms_.isEmpty()) return; + setFilterRooms(filterRooms_); + auto first_room = rooms_.first(); first_room->setPressedState(true); @@ -271,6 +273,8 @@ RoomList::highlightSelectedRoom(const QString &room_id) qobject_cast<QWidget *>(it.value().data())); } } + + selectedRoom_ = room_id; } void @@ -374,6 +378,46 @@ RoomList::closeLeaveRoomDialog(bool leaving, const QString &room_id) } void +RoomList::setFilterRooms(bool filterRooms) +{ + filterRooms_ = filterRooms; + + for (int i = 0; i < contentsLayout_->count(); i++) { + // If roomFilter_ contains the room for the current RoomInfoListItem, + // show the list item, otherwise hide it + RoomInfoListItem *listitem = + (RoomInfoListItem *)contentsLayout_->itemAt(i)->widget(); + + if (listitem != nullptr) { + if (!filterRooms) { + contentsLayout_->itemAt(i)->widget()->show(); + } else if (roomFilter_.contains(listitem->roomId())) { + contentsLayout_->itemAt(i)->widget()->show(); + } else { + contentsLayout_->itemAt(i)->widget()->hide(); + } + } + } + + if (filterRooms_ && !roomFilter_.contains(selectedRoom_)) { + RoomInfoListItem *firstVisibleRoom = nullptr; + for (int i = 0; i < contentsLayout_->count(); i++) { + QWidget *item = contentsLayout_->itemAt(i)->widget(); + if (item != nullptr && item->isVisible()) { + firstVisibleRoom = (RoomInfoListItem *)item; + break; + } + } + if (firstVisibleRoom != nullptr) { + highlightSelectedRoom(firstVisibleRoom->roomId()); + } + } else { + scrollArea_->ensureWidgetVisible( + qobject_cast<QWidget *>(rooms_.value(selectedRoom_).data())); + } +} + +void RoomList::paintEvent(QPaintEvent *) { QStyleOption opt; @@ -394,6 +438,13 @@ RoomList::syncInvites(const std::map<std::string, mtx::responses::InvitedRoom> & } void +RoomList::setRoomFilter(QList<QString> room_ids) +{ + roomFilter_ = room_ids; + setFilterRooms(true); +} + +void RoomList::addInvitedRoom(const QString &room_id, const mtx::responses::InvitedRoom &room) { auto room_item = new RoomInfoListItem(room_id, room, scrollArea_);