Improvements to Message Search (#1237)
* Ran clang-format * Implement user-specific search in message history This functionality was originally requested in #1236. This commit changes the SearchPopup::performSearch method so that only messages from specific users can be shown. In order to filter for a specific user, enter their username with a leading '@' in the search popup. You can also add an additional search phrase which will also be considered in the search. * Naive implementation for "from:" tags Rebase later? * Cleverer (?) version using Predicates Commit adds two POC predicates: one for the author of messages, and one for substring search in messages. Problems/TODOs: * Best way to register new predicates? * Clean up tags (e.g. "from:") or not? * Test combinations of different predicates * Add a predicate to check for links in messages * Remove a dumb TODO * Rewrite SearchPopup::performSearch to be cleaner * Ran clang-format on all files * Remove TODO I missed earlier * Forgot to run clang-format peepoSadDank * Re-use {}-initialization Was accidentally removed when fixing earlier merge conflict. * Does this fix line endings? No diffs are shown locally, hopefully Git doesn't lie to me. * Rename "predicates" directory to "search" Resolving one conversation in the review of #1237. * Use LinkParser in LinkPredicate Resolving a conversation in the review of #1237. * Predicates: Use unique_ptr instead of shared_ptr Resolves a conversation in the review of #1237. * Refactor of SearchPopup and AuthorPredicate Resolving some points from the review in #1237. * Moved parsing of comma-seperated values into AuthorPredicate constructor. * Rewrite SearchPopup::parsePredicates as suggested. * Deleted now redundant methods in SearchPopup. * MessagePredicate::appliesTo now takes a Message& ... instead of a MessagePtr. This resolves a conversation in the review of #1237. * Run clang-format on two files I missed * AuthorPredicate: Check for displayName & loginName Resolving conversation on #1237.
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
#include "messages/search/AuthorPredicate.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
AuthorPredicate::AuthorPredicate(const QStringList &authors)
|
||||
: authors_()
|
||||
{
|
||||
// Check if any comma-seperated values were passed and transform those
|
||||
for (const auto &entry : authors)
|
||||
{
|
||||
for (const auto &author : entry.split(',', QString::SkipEmptyParts))
|
||||
{
|
||||
this->authors_ << author;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool AuthorPredicate::appliesTo(const Message &message)
|
||||
{
|
||||
return authors_.contains(message.displayName, Qt::CaseInsensitive) ||
|
||||
authors_.contains(message.loginName, Qt::CaseInsensitive);
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include "messages/search/MessagePredicate.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
/**
|
||||
* @brief MessagePredicate checking for the author/sender of a message.
|
||||
*
|
||||
* This predicate will only allow messages that are sent by a list of users,
|
||||
* specified by their user names.
|
||||
*/
|
||||
class AuthorPredicate : public MessagePredicate
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Create an AuthorPredicate with a list of users to search for.
|
||||
*
|
||||
* @param authors a list of user names that a message should be sent from
|
||||
*/
|
||||
AuthorPredicate(const QStringList &authors);
|
||||
|
||||
/**
|
||||
* @brief Checks whether the message is authored by any of the users passed
|
||||
* in the constructor.
|
||||
*
|
||||
* @param message the message to check
|
||||
* @return true if the message was authored by one of the specified users,
|
||||
* false otherwise
|
||||
*/
|
||||
bool appliesTo(const Message &message);
|
||||
|
||||
private:
|
||||
/// Holds the user names that will be searched for
|
||||
QStringList authors_;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,22 @@
|
||||
#include "messages/search/LinkPredicate.hpp"
|
||||
#include "common/LinkParser.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
LinkPredicate::LinkPredicate()
|
||||
{
|
||||
}
|
||||
|
||||
bool LinkPredicate::appliesTo(const Message &message)
|
||||
{
|
||||
for (const auto &word :
|
||||
message.messageText.split(' ', QString::SkipEmptyParts))
|
||||
{
|
||||
if (LinkParser(word).hasMatch())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include "messages/search/MessagePredicate.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
/**
|
||||
* @brief MessagePredicate checking whether a link exists in the message.
|
||||
*
|
||||
* This predicate will only allow messages that contain a link.
|
||||
*/
|
||||
class LinkPredicate : public MessagePredicate
|
||||
{
|
||||
public:
|
||||
LinkPredicate();
|
||||
|
||||
/**
|
||||
* @brief Checks whether the message contains a link.
|
||||
*
|
||||
* @param message the message to check
|
||||
* @return true if the message contains a link, false otherwise
|
||||
*/
|
||||
bool appliesTo(const Message &message);
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include "messages/Message.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
/**
|
||||
* @brief Abstract base class for message predicates.
|
||||
*
|
||||
* Message predicates define certain features a message can satisfy.
|
||||
* Features are represented by classes derived from this abstract class.
|
||||
* A derived class must override `appliesTo` in order to test for the desired
|
||||
* feature.
|
||||
*/
|
||||
class MessagePredicate
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Checks whether this predicate applies to the passed message.
|
||||
*
|
||||
* Implementations of `appliesTo` should never change the message's content
|
||||
* in order to be compatible with other MessagePredicates.
|
||||
*
|
||||
* @param message the message to check for this predicate
|
||||
* @return true if this predicate applies, false otherwise
|
||||
*/
|
||||
virtual bool appliesTo(const Message &message) = 0;
|
||||
};
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,15 @@
|
||||
#include "messages/search/SubstringPredicate.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
SubstringPredicate::SubstringPredicate(const QString &search)
|
||||
: search_(search)
|
||||
{
|
||||
}
|
||||
|
||||
bool SubstringPredicate::appliesTo(const Message &message)
|
||||
{
|
||||
return message.messageText.contains(this->search_, Qt::CaseInsensitive);
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include "messages/search/MessagePredicate.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
/**
|
||||
* @brief MessagePredicate checking whether a substring exists in the message.
|
||||
*
|
||||
* This predicate will only allow messages that contain a certain substring in
|
||||
* their `searchText`.
|
||||
*/
|
||||
class SubstringPredicate : public MessagePredicate
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Create a SubstringPredicate with a substring to search for.
|
||||
*
|
||||
* The passed string is searched for case-insensitively.
|
||||
*
|
||||
* @param search the string to search for in the message
|
||||
*/
|
||||
SubstringPredicate(const QString &search);
|
||||
|
||||
/**
|
||||
* @brief Checks whether the message contains the substring passed in the
|
||||
* constructor.
|
||||
*
|
||||
* The check is done case-insensitively.
|
||||
*
|
||||
* @param message the message to check
|
||||
* @return true if the message contains the substring, false otherwise
|
||||
*/
|
||||
bool appliesTo(const Message &message);
|
||||
|
||||
private:
|
||||
/// Holds the substring to search for in a message's `messageText`
|
||||
const QString search_;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
Reference in New Issue
Block a user