mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
Merge branch 'Ch2Usercard'
This commit is contained in:
commit
db3402a18e
|
@ -2,6 +2,7 @@
|
|||
|
||||
## Unversioned
|
||||
|
||||
- Minor: Added customizable timeout buttons to the user info popup
|
||||
- Minor: Deprecate loading of "v1" window layouts. If you haven't updated Chatterino in more than 2 years, there's a chance you will lose your window layout.
|
||||
- Minor: Disable checking for updates on unsupported platforms (#1874)
|
||||
- Bugfix: Fix bug preventing users from setting the highlight color of the second entry in the "User" highlights tab (#1898)
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#include "singletons/Toasts.hpp"
|
||||
#include "widgets/Notebook.hpp"
|
||||
|
||||
using TimeoutButton = std::pair<QString, int>;
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class HighlightPhrase;
|
||||
|
@ -339,6 +341,13 @@ public:
|
|||
IntSetting hideSimilarMaxMessagesToCheck = {
|
||||
"/similarity/hideSimilarMaxMessagesToCheck", 3};
|
||||
|
||||
/// Timeout buttons
|
||||
|
||||
ChatterinoSetting<std::vector<TimeoutButton>> timeoutButtons = {
|
||||
"/timeouts/timeoutButtons",
|
||||
{ { "s", 1 }, { "s", 30 }, { "m", 1 }, { "m", 5 },
|
||||
{ "m", 30 }, { "h", 1 }, { "d", 1 }, { "w", 1 } } };
|
||||
|
||||
private:
|
||||
void updateModerationActions();
|
||||
};
|
||||
|
|
|
@ -85,6 +85,17 @@ namespace {
|
|||
|
||||
return channelPtr;
|
||||
};
|
||||
|
||||
const auto borderColor = QColor(255, 255, 255, 80);
|
||||
|
||||
int calculateTimeoutDuration(TimeoutButton timeout)
|
||||
{
|
||||
static const QMap<QString, int> durations{
|
||||
{"s", 1}, {"m", 60}, {"h", 3600}, {"d", 86400}, {"w", 604800},
|
||||
};
|
||||
return timeout.second * durations[timeout.first];
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
UserInfoPopup::UserInfoPopup(bool closeAutomatically)
|
||||
|
@ -628,99 +639,126 @@ UserInfoPopup::TimeoutWidget::TimeoutWidget()
|
|||
QColor color1(255, 255, 255, 80);
|
||||
QColor color2(255, 255, 255, 0);
|
||||
|
||||
int buttonWidth = 24;
|
||||
int buttonWidth = 40;
|
||||
// int buttonWidth = 24;
|
||||
int buttonWidth2 = 32;
|
||||
int buttonHeight = 32;
|
||||
|
||||
layout->setSpacing(16);
|
||||
|
||||
auto addButton = [&](Action action, const QString &text,
|
||||
const QPixmap &pixmap) {
|
||||
//auto addButton = [&](Action action, const QString &text,
|
||||
// const QPixmap &pixmap) {
|
||||
// auto vbox = layout.emplace<QVBoxLayout>().withoutMargin();
|
||||
// {
|
||||
// auto title = vbox.emplace<QHBoxLayout>().withoutMargin();
|
||||
// title->addStretch(1);
|
||||
// auto label = title.emplace<Label>(text);
|
||||
// label->setHasOffset(false);
|
||||
// label->setStyleSheet("color: #BBB");
|
||||
// title->addStretch(1);
|
||||
|
||||
// auto hbox = vbox.emplace<QHBoxLayout>().withoutMargin();
|
||||
// hbox->setSpacing(0);
|
||||
// {
|
||||
// auto button = hbox.emplace<Button>(nullptr);
|
||||
// button->setPixmap(pixmap);
|
||||
// button->setScaleIndependantSize(buttonHeight, buttonHeight);
|
||||
// button->setBorderColor(QColor(255, 255, 255, 127));
|
||||
|
||||
// QObject::connect(
|
||||
// button.getElement(), &Button::leftClicked, [this, action] {
|
||||
// this->buttonClicked.invoke(std::make_pair(action, -1));
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
//};
|
||||
|
||||
const auto addLayout = [&](const QString &text) {
|
||||
auto vbox = layout.emplace<QVBoxLayout>().withoutMargin();
|
||||
auto title = vbox.emplace<QHBoxLayout>().withoutMargin();
|
||||
title->addStretch(1);
|
||||
auto label = title.emplace<Label>(text);
|
||||
label->setStyleSheet("color: #BBB");
|
||||
label->setHasOffset(false);
|
||||
title->addStretch(1);
|
||||
|
||||
auto hbox = vbox.emplace<QHBoxLayout>().withoutMargin();
|
||||
hbox->setSpacing(0);
|
||||
return hbox;
|
||||
};
|
||||
|
||||
const auto addButton = [&](Action action, const QString &title,
|
||||
const QPixmap &pixmap) {
|
||||
auto button = addLayout(title).emplace<Button>(nullptr);
|
||||
button->setPixmap(pixmap);
|
||||
button->setScaleIndependantSize(buttonHeight, buttonHeight);
|
||||
button->setBorderColor(QColor(255, 255, 255, 127));
|
||||
|
||||
QObject::connect(
|
||||
button.getElement(), &Button::leftClicked, [this, action] {
|
||||
this->buttonClicked.invoke(std::make_pair(action, -1));
|
||||
});
|
||||
};
|
||||
|
||||
auto addTimeouts = [&](const QString &title) {
|
||||
auto hbox = addLayout(title);
|
||||
|
||||
for (const auto &item : getSettings()->timeoutButtons.getValue())
|
||||
{
|
||||
auto title = vbox.emplace<QHBoxLayout>().withoutMargin();
|
||||
title->addStretch(1);
|
||||
auto label = title.emplace<Label>(text);
|
||||
label->setHasOffset(false);
|
||||
label->setStyleSheet("color: #BBB");
|
||||
title->addStretch(1);
|
||||
auto a = hbox.emplace<EffectLabel2>();
|
||||
a->getLabel().setText(QString::number(item.second) + item.first);
|
||||
|
||||
auto hbox = vbox.emplace<QHBoxLayout>().withoutMargin();
|
||||
hbox->setSpacing(0);
|
||||
{
|
||||
auto button = hbox.emplace<Button>(nullptr);
|
||||
button->setPixmap(pixmap);
|
||||
button->setScaleIndependantSize(buttonHeight, buttonHeight);
|
||||
button->setBorderColor(QColor(255, 255, 255, 127));
|
||||
a->setScaleIndependantSize(buttonWidth, buttonHeight);
|
||||
a->setBorderColor(borderColor);
|
||||
|
||||
QObject::connect(
|
||||
button.getElement(), &Button::leftClicked, [this, action] {
|
||||
this->buttonClicked.invoke(std::make_pair(action, -1));
|
||||
});
|
||||
}
|
||||
const auto pair =
|
||||
std::make_pair(Action::Timeout, calculateTimeoutDuration(item));
|
||||
|
||||
QObject::connect(
|
||||
a.getElement(), &EffectLabel2::leftClicked,
|
||||
[this, pair] { this->buttonClicked.invoke(pair); });
|
||||
|
||||
//auto addTimeouts = [&](const QString &title_,
|
||||
// const std::vector<std::pair<QString, int>> &items) {
|
||||
// auto vbox = layout.emplace<QVBoxLayout>().withoutMargin();
|
||||
// {
|
||||
// auto title = vbox.emplace<QHBoxLayout>().withoutMargin();
|
||||
// title->addStretch(1);
|
||||
// auto label = title.emplace<Label>(title_);
|
||||
// label->setStyleSheet("color: #BBB");
|
||||
// label->setHasOffset(false);
|
||||
// title->addStretch(1);
|
||||
|
||||
// auto hbox = vbox.emplace<QHBoxLayout>().withoutMargin();
|
||||
// hbox->setSpacing(0);
|
||||
|
||||
// for (const auto &item : items)
|
||||
// {
|
||||
// auto a = hbox.emplace<EffectLabel2>();
|
||||
// a->getLabel().setText(std::get<0>(item));
|
||||
|
||||
// if (std::get<0>(item).length() > 1)
|
||||
// {
|
||||
// a->setScaleIndependantSize(buttonWidth2, buttonHeight);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// a->setScaleIndependantSize(buttonWidth, buttonHeight);
|
||||
// }
|
||||
// a->setBorderColor(color1);
|
||||
|
||||
// QObject::connect(a.getElement(), &EffectLabel2::leftClicked,
|
||||
// [this, timeout = std::get<1>(item)] {
|
||||
// this->buttonClicked.invoke(std::make_pair(
|
||||
// Action::Timeout, timeout));
|
||||
// });
|
||||
// }
|
||||
}
|
||||
};
|
||||
|
||||
auto addTimeouts = [&](const QString &title_,
|
||||
const std::vector<std::pair<QString, int>> &items) {
|
||||
auto vbox = layout.emplace<QVBoxLayout>().withoutMargin();
|
||||
{
|
||||
auto title = vbox.emplace<QHBoxLayout>().withoutMargin();
|
||||
title->addStretch(1);
|
||||
auto label = title.emplace<Label>(title_);
|
||||
label->setStyleSheet("color: #BBB");
|
||||
label->setHasOffset(false);
|
||||
title->addStretch(1);
|
||||
|
||||
auto hbox = vbox.emplace<QHBoxLayout>().withoutMargin();
|
||||
hbox->setSpacing(0);
|
||||
|
||||
for (const auto &item : items)
|
||||
{
|
||||
auto a = hbox.emplace<EffectLabel2>();
|
||||
a->getLabel().setText(std::get<0>(item));
|
||||
|
||||
if (std::get<0>(item).length() > 1)
|
||||
{
|
||||
a->setScaleIndependantSize(buttonWidth2, buttonHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
a->setScaleIndependantSize(buttonWidth, buttonHeight);
|
||||
}
|
||||
a->setBorderColor(color1);
|
||||
|
||||
QObject::connect(a.getElement(), &EffectLabel2::leftClicked,
|
||||
[this, timeout = std::get<1>(item)] {
|
||||
this->buttonClicked.invoke(std::make_pair(
|
||||
Action::Timeout, timeout));
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
addButton(Unban, "unban", getResources().buttons.unban);
|
||||
|
||||
addTimeouts("sec", {{"1", 1}});
|
||||
addTimeouts("min", {
|
||||
{"1", 1 * 60},
|
||||
{"5", 5 * 60},
|
||||
{"10", 10 * 60},
|
||||
});
|
||||
addTimeouts("hour", {
|
||||
{"1", 1 * 60 * 60},
|
||||
{"4", 4 * 60 * 60},
|
||||
});
|
||||
addTimeouts("days", {
|
||||
{"1", 1 * 60 * 60 * 24},
|
||||
{"3", 3 * 60 * 60 * 24},
|
||||
});
|
||||
addTimeouts("weeks", {
|
||||
{"1", 1 * 60 * 60 * 24 * 7},
|
||||
{"2", 2 * 60 * 60 * 24 * 7},
|
||||
});
|
||||
|
||||
addButton(Ban, "ban", getResources().buttons.ban);
|
||||
addButton(Unban, "Unban", getResources().buttons.unban);
|
||||
addTimeouts("Timeouts");
|
||||
addButton(Ban, "Ban", getResources().buttons.ban);
|
||||
}
|
||||
|
||||
void UserInfoPopup::TimeoutWidget::paintEvent(QPaintEvent *)
|
||||
|
|
89
src/widgets/settingspages/AdvancedPage.cpp
Normal file
89
src/widgets/settingspages/AdvancedPage.cpp
Normal file
|
@ -0,0 +1,89 @@
|
|||
// Timeoutbuttons
|
||||
{
|
||||
auto timeoutLayout = tabs.appendTab(new QVBoxLayout, "Timeouts");
|
||||
auto texts = timeoutLayout.emplace<QVBoxLayout>().withoutMargin();
|
||||
{
|
||||
auto infoLabel = texts.emplace<QLabel>();
|
||||
infoLabel->setText(
|
||||
"Customize your timeout buttons in seconds (s), "
|
||||
"minutes (m), hours (h), days (d) or weeks (w).");
|
||||
|
||||
infoLabel->setAlignment(Qt::AlignCenter);
|
||||
|
||||
auto maxLabel = texts.emplace<QLabel>();
|
||||
maxLabel->setText("(maximum timeout duration = 2 w)");
|
||||
maxLabel->setAlignment(Qt::AlignCenter);
|
||||
}
|
||||
texts->setContentsMargins(0, 0, 0, 15);
|
||||
texts->setSizeConstraint(QLayout::SetMaximumSize);
|
||||
|
||||
const auto valueChanged = [=] {
|
||||
const auto index = QObject::sender()->objectName().toInt();
|
||||
|
||||
const auto line = this->durationInputs_[index];
|
||||
const auto duration = line->text().toInt();
|
||||
const auto unit = this->unitInputs_[index]->currentText();
|
||||
|
||||
// safety mechanism for setting days and weeks
|
||||
if (unit == "d" && duration > 14)
|
||||
{
|
||||
line->setText("14");
|
||||
return;
|
||||
}
|
||||
else if (unit == "w" && duration > 2)
|
||||
{
|
||||
line->setText("2");
|
||||
return;
|
||||
}
|
||||
|
||||
auto timeouts = getSettings()->timeoutButtons.getValue();
|
||||
timeouts[index] = TimeoutButton{ unit, duration };
|
||||
getSettings()->timeoutButtons.setValue(timeouts);
|
||||
};
|
||||
|
||||
// build one line for each customizable button
|
||||
auto i = 0;
|
||||
for (const auto tButton : getSettings()->timeoutButtons.getValue())
|
||||
{
|
||||
const auto buttonNumber = QString::number(i);
|
||||
auto timeout = timeoutLayout.emplace<QHBoxLayout>().withoutMargin();
|
||||
|
||||
auto buttonLabel = timeout.emplace<QLabel>();
|
||||
buttonLabel->setText(QString("Button %1: ").arg(++i));
|
||||
|
||||
auto *lineEditDurationInput = new QLineEdit();
|
||||
lineEditDurationInput->setObjectName(buttonNumber);
|
||||
lineEditDurationInput->setValidator(
|
||||
new QIntValidator(1, 99, this));
|
||||
lineEditDurationInput->setText(
|
||||
QString::number(tButton.second));
|
||||
lineEditDurationInput->setAlignment(Qt::AlignRight);
|
||||
lineEditDurationInput->setMaximumWidth(30);
|
||||
timeout.append(lineEditDurationInput);
|
||||
|
||||
auto *timeoutDurationUnit = new QComboBox();
|
||||
timeoutDurationUnit->setObjectName(buttonNumber);
|
||||
timeoutDurationUnit->addItems({ "s", "m", "h", "d", "w" });
|
||||
timeoutDurationUnit->setCurrentText(tButton.first);
|
||||
timeout.append(timeoutDurationUnit);
|
||||
|
||||
QObject::connect(lineEditDurationInput,
|
||||
&QLineEdit::textChanged, this,
|
||||
valueChanged);
|
||||
|
||||
QObject::connect(timeoutDurationUnit,
|
||||
&QComboBox::currentTextChanged, this,
|
||||
valueChanged);
|
||||
|
||||
timeout->addStretch();
|
||||
|
||||
this->durationInputs_.push_back(lineEditDurationInput);
|
||||
this->unitInputs_.push_back(timeoutDurationUnit);
|
||||
|
||||
timeout->setContentsMargins(40, 0, 0, 0);
|
||||
timeout->setSizeConstraint(QLayout::SetMaximumSize);
|
||||
}
|
||||
timeoutLayout->addStretch();
|
||||
}
|
||||
// Timeoutbuttons end
|
||||
}
|
19
src/widgets/settingspages/AdvancedPage.hpp
Normal file
19
src/widgets/settingspages/AdvancedPage.hpp
Normal file
|
@ -0,0 +1,19 @@
|
|||
#pragma once
|
||||
|
||||
#include "widgets/settingspages/SettingsPage.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class AdvancedPage : public SettingsPage
|
||||
{
|
||||
public:
|
||||
AdvancedPage();
|
||||
|
||||
private:
|
||||
// list needed for dynamic timeout settings
|
||||
std::vector<QLineEdit *> durationInputs_;
|
||||
std::vector<QComboBox *> unitInputs_;
|
||||
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
|
@ -202,10 +202,99 @@ ModerationPage::ModerationPage()
|
|||
}*/
|
||||
}
|
||||
|
||||
this->addModerationButtonSettings(tabs);
|
||||
|
||||
// ---- misc
|
||||
this->itemsChangedTimer_.setSingleShot(true);
|
||||
}
|
||||
|
||||
void ModerationPage::addModerationButtonSettings(
|
||||
LayoutCreator<QTabWidget> &tabs)
|
||||
{
|
||||
auto timeoutLayout =
|
||||
tabs.appendTab(new QVBoxLayout, "User Timeout Buttons");
|
||||
auto texts = timeoutLayout.emplace<QVBoxLayout>().withoutMargin();
|
||||
{
|
||||
auto infoLabel = texts.emplace<QLabel>();
|
||||
infoLabel->setText(
|
||||
"Customize the timeout buttons in the user popup (accessible "
|
||||
"through clicking a username).\nUse seconds (s), "
|
||||
"minutes (m), hours (h), days (d) or weeks (w).");
|
||||
|
||||
infoLabel->setAlignment(Qt::AlignCenter);
|
||||
|
||||
auto maxLabel = texts.emplace<QLabel>();
|
||||
maxLabel->setText("(maximum timeout duration = 2 w)");
|
||||
maxLabel->setAlignment(Qt::AlignCenter);
|
||||
}
|
||||
texts->setContentsMargins(0, 0, 0, 15);
|
||||
texts->setSizeConstraint(QLayout::SetMaximumSize);
|
||||
|
||||
const auto valueChanged = [=] {
|
||||
const auto index = QObject::sender()->objectName().toInt();
|
||||
|
||||
const auto line = this->durationInputs_[index];
|
||||
const auto duration = line->text().toInt();
|
||||
const auto unit = this->unitInputs_[index]->currentText();
|
||||
|
||||
// safety mechanism for setting days and weeks
|
||||
if (unit == "d" && duration > 14)
|
||||
{
|
||||
line->setText("14");
|
||||
return;
|
||||
}
|
||||
else if (unit == "w" && duration > 2)
|
||||
{
|
||||
line->setText("2");
|
||||
return;
|
||||
}
|
||||
|
||||
auto timeouts = getSettings()->timeoutButtons.getValue();
|
||||
timeouts[index] = TimeoutButton{unit, duration};
|
||||
getSettings()->timeoutButtons.setValue(timeouts);
|
||||
};
|
||||
|
||||
// build one line for each customizable button
|
||||
auto i = 0;
|
||||
for (const auto tButton : getSettings()->timeoutButtons.getValue())
|
||||
{
|
||||
const auto buttonNumber = QString::number(i);
|
||||
auto timeout = timeoutLayout.emplace<QHBoxLayout>().withoutMargin();
|
||||
|
||||
auto buttonLabel = timeout.emplace<QLabel>();
|
||||
buttonLabel->setText(QString("Button %1: ").arg(++i));
|
||||
|
||||
auto *lineEditDurationInput = new QLineEdit();
|
||||
lineEditDurationInput->setObjectName(buttonNumber);
|
||||
lineEditDurationInput->setValidator(new QIntValidator(1, 99, this));
|
||||
lineEditDurationInput->setText(QString::number(tButton.second));
|
||||
lineEditDurationInput->setAlignment(Qt::AlignRight);
|
||||
lineEditDurationInput->setMaximumWidth(30);
|
||||
timeout.append(lineEditDurationInput);
|
||||
|
||||
auto *timeoutDurationUnit = new QComboBox();
|
||||
timeoutDurationUnit->setObjectName(buttonNumber);
|
||||
timeoutDurationUnit->addItems({"s", "m", "h", "d", "w"});
|
||||
timeoutDurationUnit->setCurrentText(tButton.first);
|
||||
timeout.append(timeoutDurationUnit);
|
||||
|
||||
QObject::connect(lineEditDurationInput, &QLineEdit::textChanged, this,
|
||||
valueChanged);
|
||||
|
||||
QObject::connect(timeoutDurationUnit, &QComboBox::currentTextChanged,
|
||||
this, valueChanged);
|
||||
|
||||
timeout->addStretch();
|
||||
|
||||
this->durationInputs_.push_back(lineEditDurationInput);
|
||||
this->unitInputs_.push_back(timeoutDurationUnit);
|
||||
|
||||
timeout->setContentsMargins(40, 0, 0, 0);
|
||||
timeout->setSizeConstraint(QLayout::SetMaximumSize);
|
||||
}
|
||||
timeoutLayout->addStretch();
|
||||
}
|
||||
|
||||
void ModerationPage::selectModerationActions()
|
||||
{
|
||||
this->tabWidget_->setCurrentIndex(1);
|
||||
|
|
|
@ -9,6 +9,9 @@ class QPushButton;
|
|||
|
||||
namespace chatterino {
|
||||
|
||||
template <typename X>
|
||||
class LayoutCreator;
|
||||
|
||||
class ModerationPage : public SettingsPage
|
||||
{
|
||||
public:
|
||||
|
@ -17,8 +20,13 @@ public:
|
|||
void selectModerationActions();
|
||||
|
||||
private:
|
||||
void addModerationButtonSettings(LayoutCreator<QTabWidget> &);
|
||||
|
||||
QTimer itemsChangedTimer_;
|
||||
QTabWidget *tabWidget_{};
|
||||
|
||||
std::vector<QLineEdit *> durationInputs_;
|
||||
std::vector<QComboBox *> unitInputs_;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
|
|
Loading…
Reference in a new issue