diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp
index 0377ce30..3df67fcc 100644
--- a/src/ChatPage.cpp
+++ b/src/ChatPage.cpp
@@ -267,10 +267,27 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QWidget *parent)
[this](const QString &groupId) {
current_community_ = groupId;
- if (groupId == "world")
- room_list_->removeFilter();
- else
- room_list_->applyFilter(communitiesList_->roomList(groupId));
+ if (groupId == "world") {
+ auto hidden = communitiesList_->hiddenTagsAndCommunities();
+ std::set<QString> roomsToHide = communitiesList_->roomList(groupId);
+ for (const auto &hiddenTag : hidden) {
+ auto temp = communitiesList_->roomList(hiddenTag);
+ roomsToHide.insert(temp.begin(), temp.end());
+ }
+
+ room_list_->removeFilter(roomsToHide);
+ } else {
+ auto hidden = communitiesList_->hiddenTagsAndCommunities();
+ hidden.erase(current_community_);
+
+ auto roomsToShow = communitiesList_->roomList(groupId);
+ for (const auto &hiddenTag : hidden) {
+ for (const auto &r : communitiesList_->roomList(hiddenTag))
+ roomsToShow.erase(r);
+ }
+
+ room_list_->applyFilter(roomsToShow);
+ }
});
connect(¬ificationsManager,
diff --git a/src/CommunitiesList.cpp b/src/CommunitiesList.cpp
index f3af9932..38d27864 100644
--- a/src/CommunitiesList.cpp
+++ b/src/CommunitiesList.cpp
@@ -135,6 +135,14 @@ CommunitiesList::addCommunity(const std::string &group_id)
&CommunitiesListItem::clicked,
this,
&CommunitiesList::highlightSelectedCommunity);
+ connect(list_item, &CommunitiesListItem::isDisabledChanged, this, [this]() {
+ for (const auto &community : communities_) {
+ if (community.second->isPressed()) {
+ emit highlightSelectedCommunity(community.first);
+ break;
+ }
+ }
+ });
if (group_id.empty() || group_id.front() != '+')
return;
@@ -157,7 +165,9 @@ CommunitiesList::addCommunity(const std::string &group_id)
connect(this,
&CommunitiesList::groupRoomsRetrieved,
this,
- [this](const QString &id, const std::map<QString, bool> &rooms) {
+ [this](const QString &id, const std::set<QString> &rooms) {
+ nhlog::ui()->info(
+ "Fetched rooms for {}: {}", id.toStdString(), rooms.size());
if (communities_.find(id) == communities_.end())
return;
@@ -179,9 +189,9 @@ CommunitiesList::addCommunity(const std::string &group_id)
return;
}
- std::map<QString, bool> room_ids;
+ std::set<QString> room_ids;
for (const auto &room : res.at("chunk"))
- room_ids.emplace(QString::fromStdString(room.at("room_id")), true);
+ room_ids.emplace(QString::fromStdString(room.at("room_id")));
emit groupRoomsRetrieved(id, room_ids);
});
@@ -256,7 +266,7 @@ CommunitiesList::fetchCommunityAvatar(const QString &id, const QString &avatarUr
});
}
-std::map<QString, bool>
+std::set<QString>
CommunitiesList::roomList(const QString &id) const
{
if (communityExists(id))
@@ -277,6 +287,18 @@ CommunitiesList::currentTags() const
return tags;
}
+std::set<QString>
+CommunitiesList::hiddenTagsAndCommunities() const
+{
+ std::set<QString> hiddenTags;
+ for (auto &entry : communities_) {
+ if (entry.second->isDisabled())
+ hiddenTags.insert(entry.first);
+ }
+
+ return hiddenTags;
+}
+
void
CommunitiesList::sortEntries()
{
diff --git a/src/CommunitiesList.h b/src/CommunitiesList.h
index 63f7af07..d62beb8d 100644
--- a/src/CommunitiesList.h
+++ b/src/CommunitiesList.h
@@ -24,17 +24,18 @@ public:
void addCommunity(const std::string &id);
void removeCommunity(const QString &id) { communities_.erase(id); };
- std::map<QString, bool> roomList(const QString &id) const;
+ std::set<QString> roomList(const QString &id) const;
void syncTags(const std::map<QString, RoomInfo> &info);
void setTagsForRoom(const QString &id, const std::vector<std::string> &tags);
std::vector<std::string> currentTags() const;
+ std::set<QString> hiddenTagsAndCommunities() const;
signals:
void communityChanged(const QString &id);
void avatarRetrieved(const QString &id, const QPixmap &img);
void groupProfileRetrieved(const QString &group_id, const mtx::responses::GroupProfile &);
- void groupRoomsRetrieved(const QString &group_id, const std::map<QString, bool> &res);
+ void groupRoomsRetrieved(const QString &group_id, const std::set<QString> &res);
public slots:
void updateCommunityAvatar(const QString &id, const QPixmap &img);
diff --git a/src/CommunitiesListItem.cpp b/src/CommunitiesListItem.cpp
index dca91441..01c39fdc 100644
--- a/src/CommunitiesListItem.cpp
+++ b/src/CommunitiesListItem.cpp
@@ -1,5 +1,6 @@
#include "CommunitiesListItem.h"
+#include <QMenu>
#include <QMouseEvent>
#include "Utils.h"
@@ -20,19 +21,29 @@ CommunitiesListItem::CommunitiesListItem(QString group_id, QWidget *parent)
rippleOverlay_->setClipPath(path);
rippleOverlay_->setClipping(true);
- if (groupId_ == "world")
- avatar_ = QPixmap(":/icons/icons/ui/world.png");
- else if (groupId_ == "tag:m.favourite")
- avatar_ = QPixmap(":/icons/icons/ui/star.png");
- else if (groupId_ == "tag:m.lowpriority")
- avatar_ = QPixmap(":/icons/icons/ui/lowprio.png");
- else if (groupId_.startsWith("tag:"))
- avatar_ = QPixmap(":/icons/icons/ui/tag.png");
+ menu_ = new QMenu(this);
+ hideRoomsWithTagAction_ =
+ new QAction(tr("Hide rooms with this tag or from this community"), this);
+ hideRoomsWithTagAction_->setCheckable(true);
+ menu_->addAction(hideRoomsWithTagAction_);
+ connect(menu_, &QMenu::aboutToShow, this, [this]() {
+ hideRoomsWithTagAction_->setChecked(isDisabled_);
+ });
+
+ connect(hideRoomsWithTagAction_, &QAction::triggered, this, [this](bool checked) {
+ this->setDisabled(checked);
+ });
updateTooltip();
}
void
+CommunitiesListItem::contextMenuEvent(QContextMenuEvent *event)
+{
+ menu_->popup(event->globalPos());
+}
+
+void
CommunitiesListItem::setName(QString name)
{
name_ = name;
@@ -49,6 +60,16 @@ CommunitiesListItem::setPressedState(bool state)
}
void
+CommunitiesListItem::setDisabled(bool state)
+{
+ if (isDisabled_ != state) {
+ isDisabled_ = state;
+ update();
+ emit isDisabledChanged();
+ }
+}
+
+void
CommunitiesListItem::mousePressEvent(QMouseEvent *event)
{
if (event->buttons() == Qt::RightButton) {
@@ -80,22 +101,47 @@ CommunitiesListItem::paintEvent(QPaintEvent *)
if (isPressed_)
p.fillRect(rect(), highlightedBackgroundColor_);
+ else if (isDisabled_)
+ p.fillRect(rect(), disabledBackgroundColor_);
else if (underMouse())
p.fillRect(rect(), hoverBackgroundColor_);
else
p.fillRect(rect(), backgroundColor_);
if (avatar_.isNull()) {
- QFont font;
- font.setPointSizeF(font.pointSizeF() * 1.3);
- p.setFont(font);
+ QPixmap source;
+ if (groupId_ == "world")
+ source = QPixmap(":/icons/icons/ui/world.png");
+ else if (groupId_ == "tag:m.favourite")
+ source = QPixmap(":/icons/icons/ui/star.png");
+ else if (groupId_ == "tag:m.lowpriority")
+ source = QPixmap(":/icons/icons/ui/lowprio.png");
+ else if (groupId_.startsWith("tag:"))
+ source = QPixmap(":/icons/icons/ui/tag.png");
+
+ if (source.isNull()) {
+ QFont font;
+ font.setPointSizeF(font.pointSizeF() * 1.3);
+ p.setFont(font);
+
+ p.drawLetterAvatar(utils::firstChar(resolveName()),
+ avatarFgColor_,
+ avatarBgColor_,
+ width(),
+ height(),
+ IconSize);
+ } else {
+ QPainter painter(&source);
+ painter.setCompositionMode(QPainter::CompositionMode_SourceIn);
+ painter.fillRect(source.rect(), avatarFgColor_);
+ painter.end();
- p.drawLetterAvatar(utils::firstChar(resolveName()),
- avatarFgColor_,
- avatarBgColor_,
- width(),
- height(),
- IconSize);
+ const int imageSz = 32;
+ p.drawPixmap(
+ QRect(
+ (width() - imageSz) / 2, (height() - imageSz) / 2, imageSz, imageSz),
+ source);
+ }
} else {
p.save();
diff --git a/src/CommunitiesListItem.h b/src/CommunitiesListItem.h
index 535a6ec0..a80e3200 100644
--- a/src/CommunitiesListItem.h
+++ b/src/CommunitiesListItem.h
@@ -3,17 +3,22 @@
#include <QSharedPointer>
#include <QWidget>
+#include <set>
+
#include "Config.h"
#include "ui/Theme.h"
class RippleOverlay;
class QMouseEvent;
+class QMenu;
class CommunitiesListItem : public QWidget
{
Q_OBJECT
Q_PROPERTY(QColor highlightedBackgroundColor READ highlightedBackgroundColor WRITE
setHighlightedBackgroundColor)
+ Q_PROPERTY(QColor disabledBackgroundColor READ disabledBackgroundColor WRITE
+ setDisabledBackgroundColor)
Q_PROPERTY(
QColor hoverBackgroundColor READ hoverBackgroundColor WRITE setHoverBackgroundColor)
Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor)
@@ -26,16 +31,18 @@ public:
void setName(QString name);
bool isPressed() const { return isPressed_; }
+ bool isDisabled() const { return isDisabled_; }
void setAvatar(const QImage &img);
- void setRooms(std::map<QString, bool> room_ids) { room_ids_ = std::move(room_ids); }
- void addRoom(const QString &id) { room_ids_[id] = true; }
+ void setRooms(std::set<QString> room_ids) { room_ids_ = std::move(room_ids); }
+ void addRoom(const QString &id) { room_ids_.insert(id); }
void delRoom(const QString &id) { room_ids_.erase(id); }
- std::map<QString, bool> rooms() const { return room_ids_; }
+ std::set<QString> rooms() const { return room_ids_; }
bool is_tag() const { return groupId_.startsWith("tag:"); }
QColor highlightedBackgroundColor() const { return highlightedBackgroundColor_; }
+ QColor disabledBackgroundColor() const { return disabledBackgroundColor_; }
QColor hoverBackgroundColor() const { return hoverBackgroundColor_; }
QColor backgroundColor() const { return backgroundColor_; }
@@ -43,6 +50,7 @@ public:
QColor avatarBgColor() const { return avatarBgColor_; }
void setHighlightedBackgroundColor(QColor &color) { highlightedBackgroundColor_ = color; }
+ void setDisabledBackgroundColor(QColor &color) { disabledBackgroundColor_ = color; }
void setHoverBackgroundColor(QColor &color) { hoverBackgroundColor_ = color; }
void setBackgroundColor(QColor &color) { backgroundColor_ = color; }
@@ -56,13 +64,16 @@ public:
signals:
void clicked(const QString &group_id);
+ void isDisabledChanged();
public slots:
void setPressedState(bool state);
+ void setDisabled(bool state);
protected:
void mousePressEvent(QMouseEvent *event) override;
void paintEvent(QPaintEvent *event) override;
+ void contextMenuEvent(QContextMenuEvent *event) override;
private:
const int IconSize = 36;
@@ -70,20 +81,24 @@ private:
QString resolveName() const;
void updateTooltip();
- std::map<QString, bool> room_ids_;
+ std::set<QString> room_ids_;
QString name_;
QString groupId_;
QPixmap avatar_;
QColor highlightedBackgroundColor_;
+ QColor disabledBackgroundColor_;
QColor hoverBackgroundColor_;
QColor backgroundColor_;
QColor avatarFgColor_;
QColor avatarBgColor_;
- bool isPressed_ = false;
+ bool isPressed_ = false;
+ bool isDisabled_ = false;
RippleOverlay *rippleOverlay_;
+ QMenu *menu_;
+ QAction *hideRoomsWithTagAction_;
};
diff --git a/src/MatrixClient.cpp b/src/MatrixClient.cpp
index b69ba480..669dc270 100644
--- a/src/MatrixClient.cpp
+++ b/src/MatrixClient.cpp
@@ -1,6 +1,7 @@
#include "MatrixClient.h"
#include <memory>
+#include <set>
#include <QMetaType>
#include <QObject>
@@ -21,6 +22,7 @@ Q_DECLARE_METATYPE(nlohmann::json)
Q_DECLARE_METATYPE(std::string)
Q_DECLARE_METATYPE(std::vector<std::string>)
Q_DECLARE_METATYPE(std::vector<QString>)
+Q_DECLARE_METATYPE(std::set<QString>)
namespace {
auto client_ = std::make_shared<mtx::http::Client>();
@@ -55,6 +57,7 @@ init()
qRegisterMetaType<std::vector<std::string>>();
qRegisterMetaType<std::vector<QString>>();
qRegisterMetaType<std::map<QString, bool>>("std::map<QString, bool>");
+ qRegisterMetaType<std::set<QString>>();
}
} // namespace http
diff --git a/src/RoomInfoListItem.cpp b/src/RoomInfoListItem.cpp
index 427af632..b5ba5af1 100644
--- a/src/RoomInfoListItem.cpp
+++ b/src/RoomInfoListItem.cpp
@@ -17,6 +17,7 @@
#include <QDateTime>
#include <QInputDialog>
+#include <QMenu>
#include <QMouseEvent>
#include <QPainter>
#include <QSettings>
@@ -32,7 +33,6 @@
#include "Splitter.h"
#include "UserSettingsPage.h"
#include "Utils.h"
-#include "ui/Menu.h"
#include "ui/Ripple.h"
#include "ui/RippleOverlay.h"
@@ -98,7 +98,7 @@ RoomInfoListItem::init(QWidget *parent)
bubbleDiameter_ = QFontMetrics(unreadCountFont_).averageCharWidth() * 3;
- menu_ = new Menu(this);
+ menu_ = new QMenu(this);
leaveRoom_ = new QAction(tr("Leave room"), this);
connect(leaveRoom_, &QAction::triggered, this, [this]() { emit leaveRoom(roomId_); });
diff --git a/src/RoomInfoListItem.h b/src/RoomInfoListItem.h
index af919592..baa8b98b 100644
--- a/src/RoomInfoListItem.h
+++ b/src/RoomInfoListItem.h
@@ -28,7 +28,7 @@
#include "UserSettingsPage.h"
#include "ui/Avatar.h"
-class Menu;
+class QMenu;
class RippleOverlay;
class RoomInfoListItem : public QWidget
@@ -178,7 +178,7 @@ private:
DescInfo lastMsgInfo_;
- Menu *menu_;
+ QMenu *menu_;
QAction *leaveRoom_;
bool isPressed_ = false;
diff --git a/src/RoomList.cpp b/src/RoomList.cpp
index aab89491..764a8e42 100644
--- a/src/RoomList.cpp
+++ b/src/RoomList.cpp
@@ -50,8 +50,8 @@ RoomList::RoomList(QSharedPointer<UserSettings> userSettings, QWidget *parent)
QScroller::grabGesture(scrollArea_, QScroller::TouchGesture);
QScroller::grabGesture(scrollArea_, QScroller::LeftMouseButtonGesture);
- // The scrollbar on macOS will hide itself when not active so it won't interfere
- // with the content.
+// The scrollbar on macOS will hide itself when not active so it won't interfere
+// with the content.
#if not defined(Q_OS_MAC)
scrollArea_->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
#endif
@@ -411,20 +411,24 @@ RoomList::closeJoinRoomDialog(bool isJoining, QString roomAlias)
}
void
-RoomList::removeFilter()
+RoomList::removeFilter(const std::set<QString> &roomsToHide)
{
setUpdatesEnabled(false);
for (int i = 0; i < contentsLayout_->count(); i++) {
auto widget =
qobject_cast<RoomInfoListItem *>(contentsLayout_->itemAt(i)->widget());
- if (widget)
- widget->show();
+ if (widget) {
+ if (roomsToHide.find(widget->roomId()) == roomsToHide.end())
+ widget->show();
+ else
+ widget->hide();
+ }
}
setUpdatesEnabled(true);
}
void
-RoomList::applyFilter(const std::map<QString, bool> &filter)
+RoomList::applyFilter(const std::set<QString> &filter)
{
// Disabling paint updates will resolve issues with screen flickering on big room lists.
setUpdatesEnabled(false);
diff --git a/src/RoomList.h b/src/RoomList.h
index 02aac869..5350a2ab 100644
--- a/src/RoomList.h
+++ b/src/RoomList.h
@@ -23,6 +23,8 @@
#include <QVBoxLayout>
#include <QWidget>
+#include <set>
+
#include "CacheStructs.h"
#include "UserSettingsPage.h"
@@ -54,9 +56,9 @@ public:
void addInvitedRoom(const QString &room_id, const RoomInfo &info);
void removeRoom(const QString &room_id, bool reset);
//! Hide rooms that are not present in the given filter.
- void applyFilter(const std::map<QString, bool> &rooms);
+ void applyFilter(const std::set<QString> &rooms);
//! Show all the available rooms.
- void removeFilter();
+ void removeFilter(const std::set<QString> &roomsToHide);
void updateRoom(const QString &room_id, const RoomInfo &info);
void cleanupInvites(const std::map<QString, bool> &invites);
|