diff --git a/CHANGELOG.md b/CHANGELOG.md index baded6d4a..e4d0a3057 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unversioned +- Minor: Added `in:` search filter to find messages sent in specific channels. (#2299, #2634) - Minor: Allow for built-in Chatterino commands to be used in custom commands. (#2632) - Bugfix: Fix crash that could occur when the user changed the "Custom stream player URI Scheme" setting if the user had closed down and splits in the application runtime. (#2592) diff --git a/chatterino.pro b/chatterino.pro index eddc634d6..cda40d7e0 100644 --- a/chatterino.pro +++ b/chatterino.pro @@ -179,6 +179,7 @@ SOURCES += \ src/messages/MessageContainer.cpp \ src/messages/MessageElement.cpp \ src/messages/search/AuthorPredicate.cpp \ + src/messages/search/ChannelPredicate.cpp \ src/messages/search/LinkPredicate.cpp \ src/messages/search/SubstringPredicate.cpp \ src/messages/SharedMessageBuilder.cpp \ @@ -406,6 +407,7 @@ HEADERS += \ src/messages/MessageElement.hpp \ src/messages/MessageParseArgs.hpp \ src/messages/search/AuthorPredicate.hpp \ + src/messages/search/ChannelPredicate.hpp \ src/messages/search/LinkPredicate.hpp \ src/messages/search/MessagePredicate.hpp \ src/messages/search/SubstringPredicate.hpp \ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 397ccb8d0..42b872d78 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -133,6 +133,8 @@ set(SOURCE_FILES main.cpp messages/layouts/MessageLayoutElement.hpp messages/search/AuthorPredicate.cpp messages/search/AuthorPredicate.hpp + messages/search/ChannelPredicate.cpp + messages/search/ChannelPredicate.hpp messages/search/LinkPredicate.cpp messages/search/LinkPredicate.hpp messages/search/SubstringPredicate.cpp diff --git a/src/messages/search/ChannelPredicate.cpp b/src/messages/search/ChannelPredicate.cpp new file mode 100644 index 000000000..0c1980c1f --- /dev/null +++ b/src/messages/search/ChannelPredicate.cpp @@ -0,0 +1,23 @@ +#include "messages/search/ChannelPredicate.hpp" + +namespace chatterino { + +ChannelPredicate::ChannelPredicate(const QStringList &channels) + : channels_() +{ + // Check if any comma-seperated values were passed and transform those + for (const auto &entry : channels) + { + for (const auto &channel : entry.split(',', QString::SkipEmptyParts)) + { + this->channels_ << channel; + } + } +} + +bool ChannelPredicate::appliesTo(const Message &message) +{ + return channels_.contains(message.channelName, Qt::CaseInsensitive); +} + +} // namespace chatterino diff --git a/src/messages/search/ChannelPredicate.hpp b/src/messages/search/ChannelPredicate.hpp new file mode 100644 index 000000000..08521942a --- /dev/null +++ b/src/messages/search/ChannelPredicate.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include "messages/search/MessagePredicate.hpp" + +namespace chatterino { + +/** + * @brief MessagePredicate checking for the channel a message was sent in. + * + * This predicate will only allow messages that are sent in a list of channels, + * specified by their names. + */ +class ChannelPredicate : public MessagePredicate +{ +public: + /** + * @brief Create a ChannelPredicate with a list of channels to search for. + * + * @param channels a list of channel names that a message should be sent in + */ + ChannelPredicate(const QStringList &channels); + + /** + * @brief Checks whether the message was sent in any of the channels passed + * in the constructor. + * + * @param message the message to check + * @return true if the message was sent in one of the specified channels, + * false otherwise + */ + bool appliesTo(const Message &message); + +private: + /// Holds the channel names that will be searched for + QStringList channels_; +}; + +} // namespace chatterino diff --git a/src/widgets/helper/SearchPopup.cpp b/src/widgets/helper/SearchPopup.cpp index a0b54da8a..986df3c54 100644 --- a/src/widgets/helper/SearchPopup.cpp +++ b/src/widgets/helper/SearchPopup.cpp @@ -8,6 +8,7 @@ #include "common/Channel.hpp" #include "messages/Message.hpp" #include "messages/search/AuthorPredicate.hpp" +#include "messages/search/ChannelPredicate.hpp" #include "messages/search/LinkPredicate.hpp" #include "messages/search/SubstringPredicate.hpp" #include "util/Shortcut.hpp" @@ -164,9 +165,10 @@ std::vector> SearchPopup::parsePredicates( { static QRegularExpression predicateRegex(R"(^(\w+):([\w,]+)$)"); - auto predicates = std::vector>(); + std::vector> predicates; auto words = input.split(' ', QString::SkipEmptyParts); - auto authors = QStringList(); + QStringList authors; + QStringList channels; for (auto it = words.begin(); it != words.end();) { @@ -186,6 +188,10 @@ std::vector> SearchPopup::parsePredicates( { predicates.push_back(std::make_unique()); } + else if (name == "in") + { + channels.append(value); + } else { remove = false; @@ -203,6 +209,9 @@ std::vector> SearchPopup::parsePredicates( if (!authors.empty()) predicates.push_back(std::make_unique(authors)); + if (!channels.empty()) + predicates.push_back(std::make_unique(channels)); + if (!words.empty()) predicates.push_back( std::make_unique(words.join(" ")));