diff --git a/chatterino.pro b/chatterino.pro index 56517ef3c..2d76ca824 100644 --- a/chatterino.pro +++ b/chatterino.pro @@ -83,6 +83,9 @@ SOURCES += \ src/controllers/taggedusers/TaggedUser.cpp \ src/controllers/taggedusers/TaggedUsersController.cpp \ src/controllers/taggedusers/TaggedUsersModel.cpp \ + src/controllers/timeoutbuttons/TimeoutButton.cpp \ + src/controllers/timeoutbuttons/TimeoutButtonController.cpp \ + src/controllers/timeoutbuttons/TimeoutButtonModel.cpp \ src/main.cpp \ src/messages/Emote.cpp \ src/messages/Image.cpp \ @@ -253,6 +256,9 @@ HEADERS += \ src/controllers/taggedusers/TaggedUser.hpp \ src/controllers/taggedusers/TaggedUsersController.hpp \ src/controllers/taggedusers/TaggedUsersModel.hpp \ + src/controllers/timeoutbuttons/TimeoutButton.hpp \ + src/controllers/timeoutbuttons/TimeoutButtonController.hpp \ + src/controllers/timeoutbuttons/TimeoutButtonModel.hpp \ src/messages/Emote.hpp \ src/messages/Image.hpp \ src/messages/ImageSet.hpp \ diff --git a/src/Application.hpp b/src/Application.hpp index 49c8fe96c..bc7ca721e 100644 --- a/src/Application.hpp +++ b/src/Application.hpp @@ -19,6 +19,7 @@ class AccountController; class ModerationActions; class NotificationController; class PingController; +class TimeoutButtonController; class Theme; class WindowManager; @@ -58,12 +59,12 @@ public: Emotes *const emotes{}; WindowManager *const windows{}; Toasts *const toasts{}; - AccountController *const accounts{}; CommandController *const commands{}; HighlightController *const highlights{}; NotificationController *const notifications{}; PingController *const pings{}; + TimeoutButtonController *const timeoutButtons{}; IgnoreController *const ignores{}; TaggedUsersController *const taggedUsers{}; ModerationActions *const moderationActions{}; diff --git a/src/controllers/timeoutbuttons/TimeoutButton.cpp b/src/controllers/timeoutbuttons/TimeoutButton.cpp new file mode 100644 index 000000000..337749cf9 --- /dev/null +++ b/src/controllers/timeoutbuttons/TimeoutButton.cpp @@ -0,0 +1,34 @@ +#include "TimeoutButton.hpp" + +namespace chatterino { + +TimeoutButton::TimeoutButton(const int &duration, const QString &unit) + : duration_(duration) + , unit_(unit) +{ +} + +int TimeoutButton::getDuration() const +{ + return this->duration_; +} + +QString TimeoutButton::getDurationString() const +{ + return QString::number(this->getDuration()); +} + +QString TimeoutButton::getUnit() const +{ + return this->unit_; +} + +int TimeoutButton::getTimeoutDuration() const +{ + static const QMap durations{ + {"s", 1}, {"m", 60}, {"h", 3600}, {"d", 86400}, {"w", 604800}, + }; + return this->duration_ * durations[this->unit_]; +} + +} // namespace chatterino diff --git a/src/controllers/timeoutbuttons/TimeoutButton.hpp b/src/controllers/timeoutbuttons/TimeoutButton.hpp new file mode 100644 index 000000000..ee7850c7c --- /dev/null +++ b/src/controllers/timeoutbuttons/TimeoutButton.hpp @@ -0,0 +1,63 @@ +#pragma once + +#include "util/RapidJsonSerializeQString.hpp" +#include "util/RapidjsonHelpers.hpp" + +#include +#include + +namespace chatterino { + +class TimeoutButton +{ +public: + TimeoutButton(const int &duration, const QString &unit); + + int getDuration() const; + QString getDurationString() const; + QString getUnit() const; + int getTimeoutDuration() const; + +private: + int duration_; + QString unit_; +}; + +} // namespace chatterino + +namespace pajlada { + +template <> +struct Serialize { + static rapidjson::Value get(const chatterino::TimeoutButton &value, + rapidjson::Document::AllocatorType &a) + { + rapidjson::Value ret(rapidjson::kObjectType); + + chatterino::rj::set(ret, "duration", value.getDuration(), a); + chatterino::rj::set(ret, "unit", value.getUnit(), a); + + return ret; + } +}; + +template <> +struct Deserialize { + static chatterino::TimeoutButton get(const rapidjson::Value &value) + { + if (!value.IsObject()) + { + return chatterino::TimeoutButton(int(), QString()); + } + + int _duration; + QString _unit; + + chatterino::rj::getSafe(value, "duration", _duration); + chatterino::rj::getSafe(value, "unit", _unit); + + return chatterino::TimeoutButton(_duration, _unit); + } +}; + +} // namespace pajlada diff --git a/src/controllers/timeoutbuttons/TimeoutButtonController.cpp b/src/controllers/timeoutbuttons/TimeoutButtonController.cpp new file mode 100644 index 000000000..93b9580c5 --- /dev/null +++ b/src/controllers/timeoutbuttons/TimeoutButtonController.cpp @@ -0,0 +1,33 @@ +#include "TimeoutButtonController.hpp" + +#include "controllers/timeoutbuttons/TimeoutButton.hpp" +#include "controllers/timeoutbuttons/TimeoutButtonModel.hpp" +#include "debug/Log.hpp" +#include "providers/twitch/TwitchAccount.hpp" + +namespace chatterino { + +TimeoutButtonController::TimeoutButtonController() +{ +} + +TimeoutButtonModel *TimeoutButtonController::createModel(QObject *parent) +{ + TimeoutButtonModel *model = new TimeoutButtonModel(parent); + + // this breaks NaM - idk why + model->init(&this->buttons); + + return model; +} + +void TimeoutButtonController::initialize(Settings &settings, Paths &paths) +{ + this->initialized_ = true; + log("hallo"); + for (const TimeoutButton &button : this->timeoutButtons_.getValue()) + { + this->buttons.appendItem(button); + } +} +} // namespace chatterino diff --git a/src/controllers/timeoutbuttons/TimeoutButtonController.hpp b/src/controllers/timeoutbuttons/TimeoutButtonController.hpp new file mode 100644 index 000000000..5316c05ae --- /dev/null +++ b/src/controllers/timeoutbuttons/TimeoutButtonController.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include + +#include "common/ChatterinoSetting.hpp" +#include "common/SignalVector.hpp" +#include "common/Singleton.hpp" + +namespace chatterino { + +class TimeoutButton; + +class TimeoutButtonModel; + +class Settings; + +class TimeoutButtonController final : public Singleton +{ +public: + TimeoutButtonController(); + + TimeoutButtonModel *createModel(QObject *parent); + + virtual void initialize(Settings &settings, Paths &paths) override; + + UnsortedSignalVector buttons; + +private: + bool initialized_ = false; + + ChatterinoSetting> timeoutButtons_ = { + "/timeouts/timeoutButtons"}; +}; + +} // namespace chatterino diff --git a/src/controllers/timeoutbuttons/TimeoutButtonModel.cpp b/src/controllers/timeoutbuttons/TimeoutButtonModel.cpp new file mode 100644 index 000000000..d29ad6639 --- /dev/null +++ b/src/controllers/timeoutbuttons/TimeoutButtonModel.cpp @@ -0,0 +1,29 @@ +#include "TimeoutButtonModel.hpp" + +#include "controllers/timeoutbuttons/TimeoutButton.hpp" +#include "util/StandardItemHelper.hpp" + +namespace chatterino { + +TimeoutButtonModel::TimeoutButtonModel(QObject *parent) + : SignalVectorModel(2, parent) +{ +} + +// turn a vector item into a model row +TimeoutButton TimeoutButtonModel::getItemFromRow( + std::vector &row, const TimeoutButton &original) +{ + return TimeoutButton(row[0]->data(Qt::EditRole).toInt(), + row[1]->data(Qt::EditRole).toString()); +} + +// turns a row in the model into a vector item +void TimeoutButtonModel::getRowFromItem(const TimeoutButton &item, + std::vector &row) +{ + row[0]->setData(item.getDurationString(), Qt::DisplayRole); + row[1]->setData(item.getUnit(), Qt::DisplayRole); +} + +} // namespace chatterino diff --git a/src/controllers/timeoutbuttons/TimeoutButtonModel.hpp b/src/controllers/timeoutbuttons/TimeoutButtonModel.hpp new file mode 100644 index 000000000..adcf680bd --- /dev/null +++ b/src/controllers/timeoutbuttons/TimeoutButtonModel.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include "common/SignalVectorModel.hpp" +#include "controllers/timeoutbuttons/TimeoutButton.hpp" +#include "controllers/timeoutbuttons/TimeoutButtonController.hpp" + +namespace chatterino { + +class TimeoutButton; +class TimeoutButtonController; + +class TimeoutButtonModel : public SignalVectorModel +{ +public: + TimeoutButtonModel(QObject *parent); + +protected: + // turn a vector item into a model row + virtual TimeoutButton getItemFromRow( + std::vector &row, + const TimeoutButton &original) override; + + // turns a row in the model into a vector item + virtual void getRowFromItem(const TimeoutButton &item, + std::vector &row) override; + friend class TimeoutButtonController; + +private: +}; + +} // namespace chatterino diff --git a/src/singletons/Settings.hpp b/src/singletons/Settings.hpp index a079648e3..f54de6c65 100644 --- a/src/singletons/Settings.hpp +++ b/src/singletons/Settings.hpp @@ -9,8 +9,6 @@ #include #include -using TimeoutButton = std::pair; - namespace chatterino { class Settings : public ABSettings @@ -197,13 +195,6 @@ public: QStringSetting cachePath = {"/cache/path", ""}; - /// Timeout buttons - - ChatterinoSetting> timeoutButtons = { - "/timeouts/timeoutButtons", - { { "s", 1 }, { "s", 30 }, { "m", 1 }, { "m", 5 }, - { "m", 30 }, { "h", 1 }, { "d", 1 }, { "w", 1 } } }; - private: void updateModerationActions(); }; diff --git a/src/widgets/dialogs/UserInfoPopup.cpp b/src/widgets/dialogs/UserInfoPopup.cpp index a75345dc7..73c8d5dfe 100644 --- a/src/widgets/dialogs/UserInfoPopup.cpp +++ b/src/widgets/dialogs/UserInfoPopup.cpp @@ -34,14 +34,6 @@ namespace { const auto borderColor = QColor(255, 255, 255, 80); - int calculateTimeoutDuration(TimeoutButton timeout) - { - static const QMap durations{ - {"s", 1}, {"m", 60}, {"h", 3600}, {"d", 86400}, {"w", 604800}, - }; - return timeout.second * durations[timeout.first]; - } - ChannelPtr filterMessages(const QString &userName, ChannelPtr channel) { LimitedQueueSnapshot snapshot = @@ -544,28 +536,32 @@ UserInfoPopup::TimeoutWidget::TimeoutWidget() }); }; - const auto addTimeouts = [&](const QString &title) { - auto hbox = addLayout(title); + // const auto addTimeouts = [&](const QString &title) { + // auto hbox = addLayout(title); - for (const auto &item : getSettings()->timeoutButtons.getValue()) - { - auto a = hbox.emplace(); - a->getLabel().setText(QString::number(item.second) + item.first); + // for (const auto &item : + // getSettings()->timeoutButtons.getValue()) + // { + // auto a = hbox.emplace(); + // a->getLabel().setText(QString::number(item.second) + + // item.first); - a->setScaleIndependantSize(buttonWidth, buttonHeight); - a->setBorderColor(borderColor); + // a->setScaleIndependantSize(buttonWidth, buttonHeight); + // a->setBorderColor(borderColor); - const auto pair = - std::make_pair(Action::Timeout, calculateTimeoutDuration(item)); + // const auto pair = + // std::make_pair(Action::Timeout, + // calculateTimeoutDuration(item)); - QObject::connect( - a.getElement(), &EffectLabel2::leftClicked, - [this, pair] { this->buttonClicked.invoke(pair); }); - } - }; + // QObject::connect( + // a.getElement(), &EffectLabel2::leftClicked, + // [this, pair] { this->buttonClicked.invoke(pair); }); + // } + + // }; addButton(Unban, "Unban", getApp()->resources->buttons.unban); - addTimeouts("Timeouts"); + // addTimeouts("Timeouts"); addButton(Ban, "Ban", getApp()->resources->buttons.ban); } diff --git a/src/widgets/settingspages/AdvancedPage.cpp b/src/widgets/settingspages/AdvancedPage.cpp index 35a1b70b3..97346a09a 100644 --- a/src/widgets/settingspages/AdvancedPage.cpp +++ b/src/widgets/settingspages/AdvancedPage.cpp @@ -3,11 +3,14 @@ #include "Application.hpp" #include "controllers/taggedusers/TaggedUsersController.hpp" #include "controllers/taggedusers/TaggedUsersModel.hpp" +#include "controllers/timeoutbuttons/TimeoutButtonController.hpp" +#include "controllers/timeoutbuttons/TimeoutButtonModel.hpp" #include "singletons/Logging.hpp" #include "singletons/Paths.hpp" #include "singletons/Settings.hpp" #include "util/Helpers.hpp" #include "util/LayoutCreator.hpp" +#include "widgets/helper/EditableModelView.hpp" #include #include @@ -29,6 +32,8 @@ AdvancedPage::AdvancedPage() { LayoutCreator layoutCreator(this); + auto *app = getApp(); + auto tabs = layoutCreator.emplace(); { @@ -72,10 +77,9 @@ AdvancedPage::AdvancedPage() getSettings()->cachePath = ""; // }); } - // Logs end + // Logs end - - // Timeoutbuttons + // Timeoutbuttons { auto timeoutLayout = tabs.appendTab(new QVBoxLayout, "Timeouts"); auto texts = timeoutLayout.emplace().withoutMargin(); @@ -94,75 +98,29 @@ AdvancedPage::AdvancedPage() texts->setContentsMargins(0, 0, 0, 15); texts->setSizeConstraint(QLayout::SetMaximumSize); - const auto valueChanged = [=] { - const auto index = QObject::sender()->objectName().toInt(); + EditableModelView *view = + timeoutLayout + .emplace( + app->timeoutButtons->createModel(nullptr)) + .getElement(); - const auto line = this->durationInputs_[index]; - const auto duration = line->text().toInt(); - const auto unit = this->unitInputs_[index]->currentText(); + view->setTitles({"Duration", "Unit"}); + view->getTableView()->horizontalHeader()->setSectionResizeMode( + QHeaderView::Fixed); + view->getTableView()->horizontalHeader()->setSectionResizeMode( + 0, QHeaderView::Stretch); - // 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; - } + // fourtf: make class extrend BaseWidget and add this to + // dpiChanged + QTimer::singleShot(1, [view] { + view->getTableView()->resizeColumnsToContents(); + view->getTableView()->setColumnWidth(0, 200); + }); - 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().withoutMargin(); - - auto buttonLabel = timeout.emplace(); - 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(); + view->addButtonPressed.connect([] { + getApp()->timeoutButtons->buttons.appendItem(TimeoutButton{1, "s"}); + }); } // Timeoutbuttons end } - } // namespace chatterino