diff --git a/CHANGELOG.md b/CHANGELOG.md index b890047b..7701d9bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unversioned +- Minor: Added `is:` search filter to find messages of specific types. (#2653, #2671) - Minor: Added image links to the badge context menu. (#2667) - Minor: Added a setting to hide Twitch Predictions badges. (#2668) - Minor: Optionally remove spaces between emotes, originally made for Mm2PL/Dankerino. (#2651) diff --git a/chatterino.pro b/chatterino.pro index e34df70b..d3114637 100644 --- a/chatterino.pro +++ b/chatterino.pro @@ -182,6 +182,7 @@ SOURCES += \ src/messages/search/AuthorPredicate.cpp \ src/messages/search/ChannelPredicate.cpp \ src/messages/search/LinkPredicate.cpp \ + src/messages/search/MessageFlagsPredicate.cpp \ src/messages/search/SubstringPredicate.cpp \ src/messages/SharedMessageBuilder.cpp \ src/providers/bttv/BttvEmotes.cpp \ @@ -411,6 +412,7 @@ HEADERS += \ src/messages/search/AuthorPredicate.hpp \ src/messages/search/ChannelPredicate.hpp \ src/messages/search/LinkPredicate.hpp \ + src/messages/search/MessageFlagsPredicate.hpp \ src/messages/search/MessagePredicate.hpp \ src/messages/search/SubstringPredicate.hpp \ src/messages/Selection.hpp \ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index da7779cb..2f59b1cb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -139,6 +139,8 @@ set(SOURCE_FILES main.cpp messages/search/ChannelPredicate.hpp messages/search/LinkPredicate.cpp messages/search/LinkPredicate.hpp + messages/search/MessageFlagsPredicate.cpp + messages/search/MessageFlagsPredicate.hpp messages/search/SubstringPredicate.cpp messages/search/SubstringPredicate.hpp diff --git a/src/messages/search/MessageFlagsPredicate.cpp b/src/messages/search/MessageFlagsPredicate.cpp new file mode 100644 index 00000000..da8ed64c --- /dev/null +++ b/src/messages/search/MessageFlagsPredicate.cpp @@ -0,0 +1,44 @@ +#include "messages/search/MessageFlagsPredicate.hpp" + +namespace chatterino { + +MessageFlagsPredicate::MessageFlagsPredicate(const QString &flags) + : flags_() +{ + // Check if any comma-seperated values were passed and transform those + for (const auto &flag : flags.split(',', QString::SkipEmptyParts)) + { + if (flag == "deleted" || flag == "disabled") + { + this->flags_.set(MessageFlag::Disabled); + } + else if (flag == "sub" || flag == "subscription") + { + this->flags_.set(MessageFlag::Subscription); + } + else if (flag == "timeout" || flag == "ban") + { + this->flags_.set(MessageFlag::Timeout); + } + else if (flag == "highlighted") + { + this->flags_.set(MessageFlag::Highlighted); + } + else if (flag == "system") + { + this->flags_.set(MessageFlag::System); + } + } +} + +bool MessageFlagsPredicate::appliesTo(const Message &message) +{ + // Exclude timeout messages from system flag when timeout flag isn't present + if (this->flags_.has(MessageFlag::System) && + !this->flags_.has(MessageFlag::Timeout)) + return message.flags.hasAny(flags_) && + !message.flags.has(MessageFlag::Timeout); + return message.flags.hasAny(flags_); +} + +} // namespace chatterino diff --git a/src/messages/search/MessageFlagsPredicate.hpp b/src/messages/search/MessageFlagsPredicate.hpp new file mode 100644 index 00000000..2c389654 --- /dev/null +++ b/src/messages/search/MessageFlagsPredicate.hpp @@ -0,0 +1,48 @@ +#pragma once + +#include "common/FlagsEnum.hpp" +#include "messages/search/MessagePredicate.hpp" + +namespace chatterino { + +using MessageFlags = FlagsEnum; + +/** + * @brief MessagePredicate checking for message flags. + * + * This predicate will only allow messages with a list of flags. + * Specified by user-friendly names for the flags. + */ +class MessageFlagsPredicate : public MessagePredicate +{ +public: + /** + * @brief Create a MessageFlagsPredicate with a list of flags to search for. + * + * The flags can be specified by user-friendly names. + * "deleted" and "disabled" are used for the "Disabled" flag. + * "sub" and "subscription" are used for the "Subscription" flag. + * "timeout" is used for the "Timeout" flag. + * "highlighted" is used for the "Highlighted" flag. + * "system" is used for the "System" flag. + * + * @param flags a string comma seperated list of names for the flags a message should have + */ + MessageFlagsPredicate(const QString &flags); + + /** + * @brief Checks whether the message has any of the flags passed + * in the constructor. + * + * @param message the message to check + * @return true if the message has at least one of the specified flags, + * false otherwise + */ + bool appliesTo(const Message &message); + +private: + /// Holds the flags that will be searched for + MessageFlags flags_; +}; + +} // namespace chatterino diff --git a/src/widgets/helper/SearchPopup.cpp b/src/widgets/helper/SearchPopup.cpp index 986df3c5..e6f8c8e8 100644 --- a/src/widgets/helper/SearchPopup.cpp +++ b/src/widgets/helper/SearchPopup.cpp @@ -10,6 +10,7 @@ #include "messages/search/AuthorPredicate.hpp" #include "messages/search/ChannelPredicate.hpp" #include "messages/search/LinkPredicate.hpp" +#include "messages/search/MessageFlagsPredicate.hpp" #include "messages/search/SubstringPredicate.hpp" #include "util/Shortcut.hpp" #include "widgets/helper/ChannelView.hpp" @@ -192,6 +193,11 @@ std::vector> SearchPopup::parsePredicates( { channels.append(value); } + else if (name == "is") + { + predicates.push_back( + std::make_unique(value)); + } else { remove = false;