diff --git a/src/controllers/ignores/IgnoreModel.cpp b/src/controllers/ignores/IgnoreModel.cpp index 869d2ec4f..3b495de3d 100644 --- a/src/controllers/ignores/IgnoreModel.cpp +++ b/src/controllers/ignores/IgnoreModel.cpp @@ -8,7 +8,7 @@ namespace chatterino { // commandmodel IgnoreModel::IgnoreModel(QObject *parent) - : SignalVectorModel(2, parent) + : SignalVectorModel(4, parent) { } @@ -18,8 +18,9 @@ IgnorePhrase IgnoreModel::getItemFromRow(std::vector &row, { // key, regex - return IgnorePhrase{row[0]->data(Qt::DisplayRole).toString(), - row[1]->data(Qt::CheckStateRole).toBool()}; + return IgnorePhrase{ + row[0]->data(Qt::DisplayRole).toString(), row[1]->data(Qt::CheckStateRole).toBool(), + row[2]->data(Qt::CheckStateRole).toBool(), row[3]->data(Qt::DisplayRole).toString()}; } // turns a row in the model into a vector item @@ -27,6 +28,8 @@ void IgnoreModel::getRowFromItem(const IgnorePhrase &item, std::vector @@ -16,15 +17,18 @@ class IgnorePhrase public: bool operator==(const IgnorePhrase &other) const { - return std::tie(this->pattern_, this->isRegex_) == std::tie(other.pattern_, other.isRegex_); + return std::tie(this->pattern_, this->isRegex_, this->isReplace_, this->replace_) == + std::tie(other.pattern_, other.isRegex_, other.isReplace_, other.replace_); } - IgnorePhrase(const QString &pattern, bool isRegex) + IgnorePhrase(const QString &pattern, bool isRegex, bool isReplace, const QString &replace) : pattern_(pattern) , isRegex_(isRegex) , regex_(isRegex_ ? pattern : "\\b" + QRegularExpression::escape(pattern) + "\\b", QRegularExpression::CaseInsensitiveOption | QRegularExpression::UseUnicodePropertiesOption) + , isReplace_(isReplace) + , replace_(replace) { } @@ -47,10 +51,22 @@ public: return this->isValid() && this->regex_.match(subject).hasMatch(); } + bool isReplace() const + { + return this->isReplace_; + } + + const QString &getReplace() const + { + return this->replace_; + } + private: QString pattern_; bool isRegex_; QRegularExpression regex_; + bool isReplace_; + QString replace_; }; } // namespace chatterino @@ -66,6 +82,8 @@ struct Serialize { AddMember(ret, "pattern", value.getPattern(), a); AddMember(ret, "regex", value.isRegex(), a); + AddMember(ret, "onlyWord", value.isReplace(), a); + AddMember(ret, "replace", value.getReplace(), a); return ret; } @@ -76,16 +94,22 @@ struct Deserialize { static chatterino::IgnorePhrase get(const rapidjson::Value &value) { if (!value.IsObject()) { - return chatterino::IgnorePhrase(QString(), false); + return chatterino::IgnorePhrase( + QString(), false, false, + ::chatterino::getSettings()->ignoredPhraseReplace.getValue()); } QString _pattern; bool _isRegex = false; + bool _isReplace = false; + QString _replace; chatterino::rj::getSafe(value, "pattern", _pattern); chatterino::rj::getSafe(value, "regex", _isRegex); + chatterino::rj::getSafe(value, "onlyWord", _isReplace); + chatterino::rj::getSafe(value, "replace", _replace); - return chatterino::IgnorePhrase(_pattern, _isRegex); + return chatterino::IgnorePhrase(_pattern, _isRegex, _isReplace, _replace); } }; diff --git a/src/providers/twitch/TwitchMessageBuilder.cpp b/src/providers/twitch/TwitchMessageBuilder.cpp index e54d71202..f01a78ecd 100644 --- a/src/providers/twitch/TwitchMessageBuilder.cpp +++ b/src/providers/twitch/TwitchMessageBuilder.cpp @@ -56,7 +56,7 @@ bool TwitchMessageBuilder::isIgnored() const // TODO(pajlada): Do we need to check if the phrase is valid first? for (const auto &phrase : app->ignores->phrases.getVector()) { - if (phrase.isMatch(this->originalMessage_)) { + if (!phrase.isReplace() && phrase.isMatch(this->originalMessage_)) { Log("Blocking message because it contains ignored phrase {}", phrase.getPattern()); return true; } @@ -168,13 +168,22 @@ MessagePtr TwitchMessageBuilder::build() auto currentTwitchEmote = twitchEmotes.begin(); + /*for (const auto &phrase : app->ignores->phrases.getVector()) { + if (phrase.isReplace() && phrase.isMatch(this->originalMessage_)) { + Log("Replacing message because it contains ignored phrase {}", phrase.getPattern()); + this->originalMessage_.replace(phrase.getPattern(), phrase.getReplace()); + } + }*/ + // words QStringList splits = this->originalMessage_.split(' '); long int i = 0; - for (QString split : splits) { + for (int current = 0; current < splits.size(); ++current) { + const QString &split = splits[current]; + Log("Splits {} {} {}", current, split, i); MessageColor textColor = this->action_ ? MessageColor(this->usernameColor_) : MessageColor(MessageColor::Text); diff --git a/src/providers/twitch/TwitchMessageBuilder.hpp b/src/providers/twitch/TwitchMessageBuilder.hpp index 80d80fe7b..22375b5ad 100644 --- a/src/providers/twitch/TwitchMessageBuilder.hpp +++ b/src/providers/twitch/TwitchMessageBuilder.hpp @@ -61,7 +61,7 @@ private: QString roomID_; QColor usernameColor_; - const QString originalMessage_; + QString originalMessage_; bool senderIsBroadcaster{}; const bool action_ = false; diff --git a/src/singletons/Settings.hpp b/src/singletons/Settings.hpp index ac0cbf0b8..fd30642f1 100644 --- a/src/singletons/Settings.hpp +++ b/src/singletons/Settings.hpp @@ -83,6 +83,9 @@ public: BoolSetting linksDoubleClickOnly = {"/links/doubleClickToOpen", false}; BoolSetting lowercaseLink = {"/links/linkLowercase", true}; + /// Ignored phrases + QStringSetting ignoredPhraseReplace = {"/ignore/ignoredPhraseReplace", "***"}; + /// Ingored Users BoolSetting enableTwitchIgnoredUsers = {"/ignore/enableTwitchIgnoredUsers", true}; diff --git a/src/widgets/settingspages/IgnoresPage.cpp b/src/widgets/settingspages/IgnoresPage.cpp index fe7b86d0e..6c642b0f5 100644 --- a/src/widgets/settingspages/IgnoresPage.cpp +++ b/src/widgets/settingspages/IgnoresPage.cpp @@ -45,7 +45,7 @@ void addPhrasesTab(LayoutCreator layout) { EditableModelView *view = layout.emplace(getApp()->ignores->createModel(nullptr)).getElement(); - view->setTitles({"Pattern", "Regex"}); + view->setTitles({"Pattern", "Regex", "Replace", "Pattern"}); view->getTableView()->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed); view->getTableView()->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); @@ -55,7 +55,8 @@ void addPhrasesTab(LayoutCreator layout) }); view->addButtonPressed.connect([] { - getApp()->ignores->phrases.appendItem(IgnorePhrase{"my phrase", false}); + getApp()->ignores->phrases.appendItem(IgnorePhrase{ + "my phrase", false, false, getSettings()->ignoredPhraseReplace.getValue()}); }); }