Add ability to highlight messages based on user badges (#1704)
Co-authored-by: Paweł <zneix@zneix.eu> Co-authored-by: 23rd <23rd@vivaldi.net> Co-authored-by: pajlada <rasmus.karlsson@pajlada.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#include "HighlightingPage.hpp"
|
||||
|
||||
#include "Application.hpp"
|
||||
#include "controllers/highlights/BadgeHighlightModel.hpp"
|
||||
#include "controllers/highlights/HighlightBlacklistModel.hpp"
|
||||
#include "controllers/highlights/HighlightModel.hpp"
|
||||
#include "controllers/highlights/UserHighlightModel.hpp"
|
||||
@@ -8,6 +9,7 @@
|
||||
#include "singletons/Theme.hpp"
|
||||
#include "util/LayoutCreator.hpp"
|
||||
#include "util/StandardItemHelper.hpp"
|
||||
#include "widgets/dialogs/BadgePickerDialog.hpp"
|
||||
#include "widgets/dialogs/ColorPickerDialog.hpp"
|
||||
|
||||
#include <QFileDialog>
|
||||
@@ -27,6 +29,20 @@
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
namespace {
|
||||
// Add additional badges for highlights here
|
||||
QList<DisplayBadge> availableBadges = {
|
||||
{"Broadcaster", "broadcaster"},
|
||||
{"Admin", "admin"},
|
||||
{"Staff", "staff"},
|
||||
{"Moderator", "moderator"},
|
||||
{"Verified", "partner"},
|
||||
{"VIP", "vip"},
|
||||
{"Predicted Blue", "predictions/blue-1,predictions/blue-2"},
|
||||
{"Predicted Pink", "predictions/pink-2,predictions/pink-1"},
|
||||
};
|
||||
} // namespace
|
||||
|
||||
HighlightingPage::HighlightingPage()
|
||||
{
|
||||
LayoutCreator<HighlightingPage> layoutCreator(this);
|
||||
@@ -45,7 +61,9 @@ HighlightingPage::HighlightingPage()
|
||||
{
|
||||
highlights.emplace<QLabel>(
|
||||
"Play notification sounds and highlight messages based on "
|
||||
"certain patterns.");
|
||||
"certain patterns.\n"
|
||||
"Message highlights are prioritized over badge highlights, "
|
||||
"but under user highlights");
|
||||
|
||||
auto view =
|
||||
highlights
|
||||
@@ -80,7 +98,8 @@ HighlightingPage::HighlightingPage()
|
||||
|
||||
QObject::connect(view->getTableView(), &QTableView::clicked,
|
||||
[this, view](const QModelIndex &clicked) {
|
||||
this->tableCellClicked(clicked, view);
|
||||
this->tableCellClicked(
|
||||
clicked, view, HighlightTab::Messages);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -89,7 +108,7 @@ HighlightingPage::HighlightingPage()
|
||||
pingUsers.emplace<QLabel>(
|
||||
"Play notification sounds and highlight messages from "
|
||||
"certain users.\n"
|
||||
"User highlights are prioritized over message "
|
||||
"User highlights are prioritized over message and badge "
|
||||
"highlights.");
|
||||
EditableModelView *view =
|
||||
pingUsers
|
||||
@@ -130,7 +149,61 @@ HighlightingPage::HighlightingPage()
|
||||
|
||||
QObject::connect(view->getTableView(), &QTableView::clicked,
|
||||
[this, view](const QModelIndex &clicked) {
|
||||
this->tableCellClicked(clicked, view);
|
||||
this->tableCellClicked(
|
||||
clicked, view, HighlightTab::Users);
|
||||
});
|
||||
}
|
||||
|
||||
auto badgeHighlights = tabs.appendTab(new QVBoxLayout, "Badges");
|
||||
{
|
||||
badgeHighlights.emplace<QLabel>(
|
||||
"Play notification sounds and highlight messages based on "
|
||||
"user badges.\n"
|
||||
"Badge highlights are prioritzed under user and message "
|
||||
"highlights.");
|
||||
auto view = badgeHighlights
|
||||
.emplace<EditableModelView>(
|
||||
(new BadgeHighlightModel(nullptr))
|
||||
->initialized(
|
||||
&getSettings()->highlightedBadges))
|
||||
.getElement();
|
||||
view->setTitles({"Name", "Flash\ntaskbar", "Play\nsound",
|
||||
"Custom\nsound", "Color"});
|
||||
view->getTableView()->horizontalHeader()->setSectionResizeMode(
|
||||
QHeaderView::Fixed);
|
||||
view->getTableView()->horizontalHeader()->setSectionResizeMode(
|
||||
0, QHeaderView::Stretch);
|
||||
|
||||
// fourtf: make class extrend BaseWidget and add this to
|
||||
// dpiChanged
|
||||
QTimer::singleShot(1, [view] {
|
||||
view->getTableView()->resizeColumnsToContents();
|
||||
view->getTableView()->setColumnWidth(0, 200);
|
||||
});
|
||||
|
||||
view->addButtonPressed.connect([this] {
|
||||
auto d = std::make_shared<BadgePickerDialog>(
|
||||
availableBadges, this);
|
||||
|
||||
d->setWindowTitle("Choose badge");
|
||||
if (d->exec() == QDialog::Accepted)
|
||||
{
|
||||
auto s = d->getSelection();
|
||||
if (!s)
|
||||
{
|
||||
return;
|
||||
}
|
||||
getSettings()->highlightedBadges.append(HighlightBadge{
|
||||
s->badgeName(), s->displayName(), false, false, "",
|
||||
ColorProvider::instance().color(
|
||||
ColorType::SelfHighlight)});
|
||||
}
|
||||
});
|
||||
|
||||
QObject::connect(view->getTableView(), &QTableView::clicked,
|
||||
[this, view](const QModelIndex &clicked) {
|
||||
this->tableCellClicked(
|
||||
clicked, view, HighlightTab::Badges);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -209,73 +282,97 @@ HighlightingPage::HighlightingPage()
|
||||
|
||||
// ---- misc
|
||||
this->disabledUsersChangedTimer_.setSingleShot(true);
|
||||
} // namespace chatterino
|
||||
}
|
||||
|
||||
void HighlightingPage::tableCellClicked(const QModelIndex &clicked,
|
||||
EditableModelView *view)
|
||||
void HighlightingPage::openSoundDialog(const QModelIndex &clicked,
|
||||
EditableModelView *view, int soundColumn)
|
||||
{
|
||||
using Column = HighlightModel::Column;
|
||||
auto fileUrl = QFileDialog::getOpenFileUrl(this, tr("Open Sound"), QUrl(),
|
||||
tr("Audio Files (*.mp3 *.wav)"));
|
||||
view->getModel()->setData(clicked, fileUrl, Qt::UserRole);
|
||||
view->getModel()->setData(clicked, fileUrl.fileName(), Qt::DisplayRole);
|
||||
|
||||
if (clicked.column() == Column::SoundPath)
|
||||
// Enable custom sound check box if user set a sound
|
||||
if (!fileUrl.isEmpty())
|
||||
{
|
||||
auto fileUrl = QFileDialog::getOpenFileUrl(
|
||||
this, tr("Open Sound"), QUrl(), tr("Audio Files (*.mp3 *.wav)"));
|
||||
view->getModel()->setData(clicked, fileUrl, Qt::UserRole);
|
||||
view->getModel()->setData(clicked, fileUrl.fileName(), Qt::DisplayRole);
|
||||
|
||||
// Enable custom sound check box if user set a sound
|
||||
if (!fileUrl.isEmpty())
|
||||
{
|
||||
QModelIndex checkBox = clicked.siblingAtColumn(Column::PlaySound);
|
||||
view->getModel()->setData(checkBox, Qt::Checked,
|
||||
Qt::CheckStateRole);
|
||||
}
|
||||
QModelIndex checkBox = clicked.siblingAtColumn(soundColumn);
|
||||
view->getModel()->setData(checkBox, Qt::Checked, Qt::CheckStateRole);
|
||||
}
|
||||
else if (clicked.column() == Column::Color)
|
||||
{
|
||||
// Hacky (?) way to figure out what tab the cell was clicked in
|
||||
const bool fromMessagesTab =
|
||||
(dynamic_cast<HighlightModel *>(view->getModel()) != nullptr);
|
||||
}
|
||||
|
||||
if (fromMessagesTab && clicked.row() == HighlightModel::WHISPER_ROW)
|
||||
return;
|
||||
void HighlightingPage::openColorDialog(const QModelIndex &clicked,
|
||||
EditableModelView *view,
|
||||
HighlightTab tab)
|
||||
{
|
||||
auto initial =
|
||||
view->getModel()->data(clicked, Qt::DecorationRole).value<QColor>();
|
||||
|
||||
auto initial =
|
||||
view->getModel()->data(clicked, Qt::DecorationRole).value<QColor>();
|
||||
auto dialog = new ColorPickerDialog(initial, this);
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
dialog->show();
|
||||
dialog->closed.connect([=](auto selected) {
|
||||
if (selected.isValid())
|
||||
{
|
||||
view->getModel()->setData(clicked, selected, Qt::DecorationRole);
|
||||
|
||||
auto dialog = new ColorPickerDialog(initial, this);
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
dialog->show();
|
||||
dialog->closed.connect([=](QColor selected) {
|
||||
if (selected.isValid())
|
||||
if (tab == HighlightTab::Messages)
|
||||
{
|
||||
view->getModel()->setData(clicked, selected,
|
||||
Qt::DecorationRole);
|
||||
|
||||
if (fromMessagesTab)
|
||||
/*
|
||||
* For preset highlights in the "Messages" tab, we need to
|
||||
* manually update the color map.
|
||||
*/
|
||||
auto instance = ColorProvider::instance();
|
||||
switch (clicked.row())
|
||||
{
|
||||
/*
|
||||
* For preset highlights in the "Messages" tab, we need to
|
||||
* manually update the color map.
|
||||
*/
|
||||
auto instance = ColorProvider::instance();
|
||||
switch (clicked.row())
|
||||
{
|
||||
case 0:
|
||||
instance.updateColor(ColorType::SelfHighlight,
|
||||
selected);
|
||||
break;
|
||||
case 1:
|
||||
instance.updateColor(ColorType::Whisper, selected);
|
||||
break;
|
||||
case 2:
|
||||
instance.updateColor(ColorType::Subscription,
|
||||
selected);
|
||||
break;
|
||||
}
|
||||
case 0:
|
||||
instance.updateColor(ColorType::SelfHighlight,
|
||||
selected);
|
||||
break;
|
||||
case 1:
|
||||
instance.updateColor(ColorType::Whisper, selected);
|
||||
break;
|
||||
case 2:
|
||||
instance.updateColor(ColorType::Subscription, selected);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void HighlightingPage::tableCellClicked(const QModelIndex &clicked,
|
||||
EditableModelView *view,
|
||||
HighlightTab tab)
|
||||
{
|
||||
switch (tab)
|
||||
{
|
||||
case HighlightTab::Messages:
|
||||
case HighlightTab::Users: {
|
||||
using Column = HighlightModel::Column;
|
||||
if (clicked.column() == Column::SoundPath)
|
||||
{
|
||||
this->openSoundDialog(clicked, view, Column::SoundPath);
|
||||
}
|
||||
else if (clicked.column() == Column::Color &&
|
||||
clicked.row() != HighlightModel::WHISPER_ROW)
|
||||
{
|
||||
this->openColorDialog(clicked, view, tab);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case HighlightTab::Badges: {
|
||||
using Column = BadgeHighlightModel::Column;
|
||||
if (clicked.column() == Column::SoundPath)
|
||||
{
|
||||
this->openSoundDialog(clicked, view, Column::SoundPath);
|
||||
}
|
||||
else if (clicked.column() == Column::Color)
|
||||
{
|
||||
this->openColorDialog(clicked, view, tab);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user