Allow users to hide rooms with specific tags

This commit is contained in:
Nicolas Werner 2021-01-23 00:30:45 +01:00
parent 97340bed13
commit fdb9d7ab40
13 changed files with 159 additions and 46 deletions

View file

@ -155,11 +155,12 @@ RoomInfoListItem > Avatar {
CommunitiesListItem {
qproperty-highlightedBackgroundColor: #4d84c7;
qproperty-disabledBackgroundColor: palette(mid);
qproperty-hoverBackgroundColor: rgb(67, 70, 77);
qproperty-backgroundColor: #2d3139;
qproperty-avatarBgColor: #202228;
qproperty-avatarFgColor: palette(window);
qproperty-avatarFgColor: black;
}
LoadingIndicator {

View file

@ -122,11 +122,12 @@ RoomInfoListItem > Avatar {
CommunitiesListItem {
qproperty-highlightedBackgroundColor: #38A3D8;
qproperty-disabledBackgroundColor: palette(mid);
qproperty-hoverBackgroundColor: rgb(70, 77, 93);
qproperty-backgroundColor: #f2f5f8;
qproperty-avatarBgColor: #eee;
qproperty-avatarFgColor: black;
qproperty-avatarFgColor: palette(buttonText);
}
#ChatPageLoadSpinner {

View file

@ -118,6 +118,7 @@ RoomInfoListItem > Avatar {
CommunitiesListItem {
qproperty-highlightedBackgroundColor: palette(highlight);
qproperty-disabledBackgroundColor: palette(mid);
qproperty-hoverBackgroundColor: palette(light);
qproperty-backgroundColor: palette(window);

View file

@ -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(&notificationsManager,

View file

@ -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()
{

View file

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

View file

@ -1,5 +1,6 @@
#include "CommunitiesListItem.h"
#include <QMenu>
#include <QMouseEvent>
#include "Utils.h"
@ -20,18 +21,28 @@ 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)
{
@ -48,6 +59,16 @@ CommunitiesListItem::setPressedState(bool state)
}
}
void
CommunitiesListItem::setDisabled(bool state)
{
if (isDisabled_ != state) {
isDisabled_ = state;
update();
emit isDisabledChanged();
}
}
void
CommunitiesListItem::mousePressEvent(QMouseEvent *event)
{
@ -80,12 +101,25 @@ 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()) {
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);
@ -96,6 +130,18 @@ CommunitiesListItem::paintEvent(QPaintEvent *)
width(),
height(),
IconSize);
} else {
QPainter painter(&source);
painter.setCompositionMode(QPainter::CompositionMode_SourceIn);
painter.fillRect(source.rect(), avatarFgColor_);
painter.end();
const int imageSz = 32;
p.drawPixmap(
QRect(
(width() - imageSz) / 2, (height() - imageSz) / 2, imageSz, imageSz),
source);
}
} else {
p.save();

View file

@ -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,13 +81,14 @@ 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_;
@ -84,6 +96,9 @@ private:
QColor avatarBgColor_;
bool isPressed_ = false;
bool isDisabled_ = false;
RippleOverlay *rippleOverlay_;
QMenu *menu_;
QAction *hideRoomsWithTagAction_;
};

View file

@ -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

View file

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

View file

@ -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;

View file

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

View file

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