mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-25 04:28:49 +03:00
Allow users to hide rooms with specific tags
This commit is contained in:
parent
97340bed13
commit
fdb9d7ab40
13 changed files with 159 additions and 46 deletions
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -118,6 +118,7 @@ RoomInfoListItem > Avatar {
|
|||
|
||||
CommunitiesListItem {
|
||||
qproperty-highlightedBackgroundColor: palette(highlight);
|
||||
qproperty-disabledBackgroundColor: palette(mid);
|
||||
qproperty-hoverBackgroundColor: palette(light);
|
||||
qproperty-backgroundColor: palette(window);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,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");
|
||||
|
||||
p.drawLetterAvatar(utils::firstChar(resolveName()),
|
||||
avatarFgColor_,
|
||||
avatarBgColor_,
|
||||
width(),
|
||||
height(),
|
||||
IconSize);
|
||||
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();
|
||||
|
||||
const int imageSz = 32;
|
||||
p.drawPixmap(
|
||||
QRect(
|
||||
(width() - imageSz) / 2, (height() - imageSz) / 2, imageSz, imageSz),
|
||||
source);
|
||||
}
|
||||
} else {
|
||||
p.save();
|
||||
|
||||
|
|
|
@ -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_;
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_); });
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue