mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
Allow non-message phrases to be highlighted by self (#3835)
* All non-phrase highlights can now trigger on messages from self New state: Allows self highlights: Subscription, Whisper, User, Badge Does not allow self highlights: Message * Add changelog entry * fix PR number in changelog
This commit is contained in:
parent
881986d86f
commit
8bdfbf7b87
|
@ -39,7 +39,7 @@
|
||||||
- Bugfix: Add icon in the CMake macOS bundle. (#3832)
|
- Bugfix: Add icon in the CMake macOS bundle. (#3832)
|
||||||
- Bugfix: Adopt popup windows in order to force floating behavior on some window managers. (#3836)
|
- Bugfix: Adopt popup windows in order to force floating behavior on some window managers. (#3836)
|
||||||
- Dev: Rewrite LimitedQueue (#3798)
|
- Dev: Rewrite LimitedQueue (#3798)
|
||||||
- Dev: Overhaul highlight system by moving all checks into a Controller allowing for easier tests. (#3399, #3801)
|
- Dev: Overhaul highlight system by moving all checks into a Controller allowing for easier tests. (#3399, #3801, #3835)
|
||||||
- Dev: Use Game Name returned by Get Streams instead of querying it from the Get Games API. (#3662)
|
- Dev: Use Game Name returned by Get Streams instead of querying it from the Get Games API. (#3662)
|
||||||
- Dev: Batch checking live status for all channels after startup. (#3757, #3762, #3767)
|
- Dev: Batch checking live status for all channels after startup. (#3757, #3762, #3767)
|
||||||
- Dev: Move most command context into the command controller. (#3824)
|
- Dev: Move most command context into the command controller. (#3824)
|
||||||
|
|
|
@ -6,15 +6,21 @@ namespace {
|
||||||
|
|
||||||
using namespace chatterino;
|
using namespace chatterino;
|
||||||
|
|
||||||
auto highlightPhraseCheck(HighlightPhrase highlight) -> HighlightCheck
|
auto highlightPhraseCheck(const HighlightPhrase &highlight) -> HighlightCheck
|
||||||
{
|
{
|
||||||
return HighlightCheck{
|
return HighlightCheck{
|
||||||
[highlight](
|
[highlight](const auto &args, const auto &badges,
|
||||||
const auto &args, const auto &badges, const auto &senderName,
|
const auto &senderName, const auto &originalMessage,
|
||||||
const auto &originalMessage) -> boost::optional<HighlightResult> {
|
const auto self) -> boost::optional<HighlightResult> {
|
||||||
(void)args; // unused
|
(void)args; // unused
|
||||||
(void)badges; // unused
|
(void)badges; // unused
|
||||||
(void)originalMessage; // unused
|
(void)senderName; // unused
|
||||||
|
|
||||||
|
if (self)
|
||||||
|
{
|
||||||
|
// Phrase checks should ignore highlights from the user
|
||||||
|
return boost::none;
|
||||||
|
}
|
||||||
|
|
||||||
if (!highlight.isMatch(originalMessage))
|
if (!highlight.isMatch(originalMessage))
|
||||||
{
|
{
|
||||||
|
@ -54,11 +60,13 @@ void rebuildSubscriptionHighlights(Settings &settings,
|
||||||
|
|
||||||
checks.emplace_back(HighlightCheck{
|
checks.emplace_back(HighlightCheck{
|
||||||
[=](const auto &args, const auto &badges, const auto &senderName,
|
[=](const auto &args, const auto &badges, const auto &senderName,
|
||||||
const auto &originalMessage)
|
const auto &originalMessage,
|
||||||
-> boost::optional<HighlightResult> {
|
const auto self) -> boost::optional<HighlightResult> {
|
||||||
(void)badges; // unused
|
(void)badges; // unused
|
||||||
(void)senderName; // unused
|
(void)senderName; // unused
|
||||||
(void)originalMessage; // unused
|
(void)originalMessage; // unused
|
||||||
|
(void)self; // unused
|
||||||
|
|
||||||
if (!args.isSubscriptionMessage)
|
if (!args.isSubscriptionMessage)
|
||||||
{
|
{
|
||||||
return boost::none;
|
return boost::none;
|
||||||
|
@ -97,11 +105,13 @@ void rebuildWhisperHighlights(Settings &settings,
|
||||||
|
|
||||||
checks.emplace_back(HighlightCheck{
|
checks.emplace_back(HighlightCheck{
|
||||||
[=](const auto &args, const auto &badges, const auto &senderName,
|
[=](const auto &args, const auto &badges, const auto &senderName,
|
||||||
const auto &originalMessage)
|
const auto &originalMessage,
|
||||||
-> boost::optional<HighlightResult> {
|
const auto self) -> boost::optional<HighlightResult> {
|
||||||
(void)badges; // unused
|
(void)badges; // unused
|
||||||
(void)senderName; // unused
|
(void)senderName; // unused
|
||||||
(void)originalMessage; // unused
|
(void)originalMessage; // unused
|
||||||
|
(void)self; // unused
|
||||||
|
|
||||||
if (!args.isReceivedWhisper)
|
if (!args.isReceivedWhisper)
|
||||||
{
|
{
|
||||||
return boost::none;
|
return boost::none;
|
||||||
|
@ -152,11 +162,12 @@ void rebuildUserHighlights(Settings &settings,
|
||||||
{
|
{
|
||||||
checks.emplace_back(HighlightCheck{
|
checks.emplace_back(HighlightCheck{
|
||||||
[highlight](const auto &args, const auto &badges,
|
[highlight](const auto &args, const auto &badges,
|
||||||
const auto &senderName, const auto &originalMessage)
|
const auto &senderName, const auto &originalMessage,
|
||||||
-> boost::optional<HighlightResult> {
|
const auto self) -> boost::optional<HighlightResult> {
|
||||||
(void)args; // unused
|
(void)args; // unused
|
||||||
(void)badges; // unused
|
(void)badges; // unused
|
||||||
(void)originalMessage; // unused
|
(void)originalMessage; // unused
|
||||||
|
(void)self; // unused
|
||||||
|
|
||||||
if (!highlight.isMatch(senderName))
|
if (!highlight.isMatch(senderName))
|
||||||
{
|
{
|
||||||
|
@ -187,11 +198,13 @@ void rebuildBadgeHighlights(Settings &settings,
|
||||||
{
|
{
|
||||||
checks.emplace_back(HighlightCheck{
|
checks.emplace_back(HighlightCheck{
|
||||||
[highlight](const auto &args, const auto &badges,
|
[highlight](const auto &args, const auto &badges,
|
||||||
const auto &senderName, const auto &originalMessage)
|
const auto &senderName, const auto &originalMessage,
|
||||||
-> boost::optional<HighlightResult> {
|
const auto self) -> boost::optional<HighlightResult> {
|
||||||
(void)args; // unused
|
(void)args; // unused
|
||||||
(void)senderName; // unused
|
(void)senderName; // unused
|
||||||
(void)originalMessage; // unused
|
(void)originalMessage; // unused
|
||||||
|
(void)self; // unused
|
||||||
|
|
||||||
for (const Badge &badge : badges)
|
for (const Badge &badge : badges)
|
||||||
{
|
{
|
||||||
if (highlight.isMatch(badge))
|
if (highlight.isMatch(badge))
|
||||||
|
@ -302,10 +315,13 @@ std::pair<bool, HighlightResult> HighlightController::check(
|
||||||
// Access for checking
|
// Access for checking
|
||||||
const auto checks = this->checks_.accessConst();
|
const auto checks = this->checks_.accessConst();
|
||||||
|
|
||||||
|
auto currentUser = getIApp()->getAccounts()->twitch.getCurrent();
|
||||||
|
auto self = (senderName == currentUser->getUserName());
|
||||||
|
|
||||||
for (const auto &check : *checks)
|
for (const auto &check : *checks)
|
||||||
{
|
{
|
||||||
if (auto checkResult =
|
if (auto checkResult =
|
||||||
check.cb(args, badges, senderName, originalMessage);
|
check.cb(args, badges, senderName, originalMessage, self);
|
||||||
checkResult)
|
checkResult)
|
||||||
{
|
{
|
||||||
highlighted = true;
|
highlighted = true;
|
||||||
|
|
|
@ -142,7 +142,7 @@ struct HighlightResult {
|
||||||
struct HighlightCheck {
|
struct HighlightCheck {
|
||||||
using Checker = std::function<boost::optional<HighlightResult>(
|
using Checker = std::function<boost::optional<HighlightResult>(
|
||||||
const MessageParseArgs &args, const std::vector<Badge> &badges,
|
const MessageParseArgs &args, const std::vector<Badge> &badges,
|
||||||
const QString &senderName, const QString &originalMessage)>;
|
const QString &senderName, const QString &originalMessage, bool self)>;
|
||||||
Checker cb;
|
Checker cb;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -147,13 +147,6 @@ void SharedMessageBuilder::parseHighlights()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto currentUser = getIApp()->getAccounts()->twitch.getCurrent();
|
|
||||||
if (this->ircMessage->nick() == currentUser->getUserName())
|
|
||||||
{
|
|
||||||
// Do nothing. We ignore any potential highlights from the logged in user
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto badges = SharedMessageBuilder::parseBadgeTag(this->tags);
|
auto badges = SharedMessageBuilder::parseBadgeTag(this->tags);
|
||||||
auto [highlighted, highlightResult] = getIApp()->getHighlights()->check(
|
auto [highlighted, highlightResult] = getIApp()->getHighlights()->check(
|
||||||
this->args, badges, this->ircMessage->nick(), this->originalMessage_);
|
this->args, badges, this->ircMessage->nick(), this->originalMessage_);
|
||||||
|
|
|
@ -245,6 +245,16 @@ static QString DEFAULT_SETTINGS = R"!(
|
||||||
"soundUrl": "",
|
"soundUrl": "",
|
||||||
"color": "#7fffffff"
|
"color": "#7fffffff"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"pattern": "testaccount_420",
|
||||||
|
"showInMentions": false,
|
||||||
|
"alert": false,
|
||||||
|
"sound": false,
|
||||||
|
"regex": false,
|
||||||
|
"case": false,
|
||||||
|
"soundUrl": "",
|
||||||
|
"color": "#6fffffff"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"pattern": "gempir",
|
"pattern": "gempir",
|
||||||
"showInMentions": true,
|
"showInMentions": true,
|
||||||
|
@ -497,6 +507,27 @@ TEST_F(HighlightControllerTest, A)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
// TEST CASE: Message phrase from sender should be ignored (so showInMentions false), but since it's a user highlight, it should set a color
|
||||||
|
{
|
||||||
|
// input
|
||||||
|
MessageParseArgs{}, // no special args
|
||||||
|
{}, // no badges
|
||||||
|
"testaccount_420", // sender name
|
||||||
|
"!testmanxd", // original message
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// expected
|
||||||
|
true, // state
|
||||||
|
{
|
||||||
|
false, // alert
|
||||||
|
false, // playsound
|
||||||
|
boost::none, // custom sound url
|
||||||
|
std::make_shared<QColor>("#6fffffff"), // color
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const auto &[input, expected] : tests)
|
for (const auto &[input, expected] : tests)
|
||||||
|
@ -504,7 +535,9 @@ TEST_F(HighlightControllerTest, A)
|
||||||
auto [isMatch, matchResult] = this->controller->check(
|
auto [isMatch, matchResult] = this->controller->check(
|
||||||
input.args, input.badges, input.senderName, input.originalMessage);
|
input.args, input.badges, input.senderName, input.originalMessage);
|
||||||
|
|
||||||
EXPECT_EQ(isMatch, expected.state);
|
EXPECT_EQ(isMatch, expected.state)
|
||||||
|
<< qUtf8Printable(input.senderName) << ": "
|
||||||
|
<< qUtf8Printable(input.originalMessage);
|
||||||
EXPECT_EQ(matchResult, expected.result);
|
EXPECT_EQ(matchResult, expected.result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue