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_);
|