mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-21 22:24:07 +01:00
Makes it possible to hide one man spam (#1496)
This commit is contained in:
parent
497ce2d2f2
commit
1fd64be7f5
9 changed files with 164 additions and 1 deletions
|
@ -3,6 +3,7 @@
|
|||
#include "Application.hpp"
|
||||
#include "messages/Message.hpp"
|
||||
#include "messages/MessageBuilder.hpp"
|
||||
#include "providers/twitch/IrcMessageHandler.hpp"
|
||||
#include "singletons/Emotes.hpp"
|
||||
#include "singletons/Logging.hpp"
|
||||
#include "singletons/Settings.hpp"
|
||||
|
|
|
@ -33,6 +33,7 @@ enum class MessageFlag : uint32_t {
|
|||
Whisper = (1 << 16),
|
||||
HighlightedWhisper = (1 << 17),
|
||||
Debug = (1 << 18),
|
||||
Similar = (1 << 19),
|
||||
};
|
||||
using MessageFlags = FlagsEnum<MessageFlag>;
|
||||
|
||||
|
|
|
@ -141,6 +141,12 @@ void MessageLayout::actuallyLayout(int width, MessageElementFlags flags)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (getSettings()->hideSimilar &&
|
||||
this->message_->flags.has(MessageFlag::Similar))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
element->addToContainer(*this->container_, flags);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,97 @@
|
|||
|
||||
namespace chatterino {
|
||||
|
||||
static float relativeSimilarity(const QString &str1, const QString &str2)
|
||||
{
|
||||
// Longest Common Substring Problem
|
||||
std::vector<std::vector<int>> tree(str1.size(),
|
||||
std::vector<int>(str2.size(), 0));
|
||||
int z = 0;
|
||||
|
||||
for (int i = 0; i < str1.size(); ++i)
|
||||
{
|
||||
for (int j = 0; j < str2.size(); ++j)
|
||||
{
|
||||
if (str1[i] == str2[j])
|
||||
{
|
||||
if (i == 0 || j == 0)
|
||||
{
|
||||
tree[i][j] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
tree[i][j] = tree[i - 1][j - 1] + 1;
|
||||
}
|
||||
if (tree[i][j] > z)
|
||||
{
|
||||
z = tree[i][j];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tree[i][j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return z == 0 ? 0.f : float(z) / std::max(str1.size(), str2.size());
|
||||
};
|
||||
|
||||
float IrcMessageHandler::similarity(
|
||||
MessagePtr msg, const LimitedQueueSnapshot<MessagePtr> &messages)
|
||||
{
|
||||
float similarityPercent = 0.0f;
|
||||
int bySameUser = 0;
|
||||
for (int i = 1; bySameUser < getSettings()->hideSimilarMaxMessagesToCheck;
|
||||
++i)
|
||||
{
|
||||
if (messages.size() < i)
|
||||
{
|
||||
break;
|
||||
}
|
||||
const auto &prevMsg = messages[messages.size() - i];
|
||||
if (prevMsg->parseTime.secsTo(QTime::currentTime()) >=
|
||||
getSettings()->hideSimilarMaxDelay)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (msg->loginName != prevMsg->loginName)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
++bySameUser;
|
||||
similarityPercent = std::max(
|
||||
similarityPercent,
|
||||
relativeSimilarity(msg->messageText, prevMsg->messageText));
|
||||
}
|
||||
return similarityPercent;
|
||||
}
|
||||
|
||||
void IrcMessageHandler::setSimilarityFlags(MessagePtr msg, ChannelPtr chan)
|
||||
{
|
||||
if (getSettings()->similarityEnabled)
|
||||
{
|
||||
bool isMyself = msg->loginName ==
|
||||
getApp()->accounts->twitch.getCurrent()->getUserName();
|
||||
bool hideMyself = getSettings()->hideSimilarMyself;
|
||||
|
||||
if (isMyself && !hideMyself)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (IrcMessageHandler::similarity(msg, chan->getMessageSnapshot()) >
|
||||
getSettings()->similarityPercentage)
|
||||
{
|
||||
msg->flags.set(MessageFlag::Similar, true);
|
||||
if (getSettings()->colorSimilarDisabled)
|
||||
{
|
||||
msg->flags.set(MessageFlag::Disabled, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static QMap<QString, QString> parseBadges(QString badgesString)
|
||||
{
|
||||
QMap<QString, QString> badges;
|
||||
|
@ -133,7 +224,16 @@ void IrcMessageHandler::addMessage(Communi::IrcMessage *_message,
|
|||
}
|
||||
|
||||
auto msg = builder.build();
|
||||
|
||||
IrcMessageHandler::setSimilarityFlags(msg, chan);
|
||||
|
||||
if (!msg->flags.has(MessageFlag::Similar) ||
|
||||
(!getSettings()->hideSimilar &&
|
||||
getSettings()->shownSimilarTriggerHighlights))
|
||||
{
|
||||
builder.triggerHighlights();
|
||||
}
|
||||
|
||||
auto highlighted = msg->flags.has(MessageFlag::Highlighted);
|
||||
|
||||
if (!isSub)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <IrcMessage>
|
||||
#include "common/Channel.hpp"
|
||||
#include "messages/Message.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
@ -49,6 +50,10 @@ public:
|
|||
void handleJoinMessage(Communi::IrcMessage *message);
|
||||
void handlePartMessage(Communi::IrcMessage *message);
|
||||
|
||||
static float similarity(MessagePtr msg,
|
||||
const LimitedQueueSnapshot<MessagePtr> &messages);
|
||||
static void setSimilarityFlags(MessagePtr message, ChannelPtr channel);
|
||||
|
||||
private:
|
||||
void addMessage(Communi::IrcMessage *message, const QString &target,
|
||||
const QString &content, TwitchIrcServer &server,
|
||||
|
|
|
@ -249,6 +249,20 @@ public:
|
|||
IntSetting lastSelectChannelTab = {"/ui/lastSelectChannelTab", 0};
|
||||
IntSetting lastSelectIrcConn = {"/ui/lastSelectIrcConn", 0};
|
||||
|
||||
// Similarity
|
||||
BoolSetting similarityEnabled = {"/similarity/similarityEnabled", false};
|
||||
BoolSetting colorSimilarDisabled = {"/similarity/colorSimilarDisabled",
|
||||
true};
|
||||
BoolSetting hideSimilar = {"/similarity/hideSimilar", false};
|
||||
BoolSetting hideSimilarMyself = {"/similarity/hideSimilarMyself", false};
|
||||
BoolSetting shownSimilarTriggerHighlights = {
|
||||
"/similarity/shownSimilarTriggerHighlights", false};
|
||||
FloatSetting similarityPercentage = {"/similarity/similarityPercentage",
|
||||
0.9f};
|
||||
IntSetting hideSimilarMaxDelay = {"/similarity/hideSimilarMaxDelay", 5};
|
||||
IntSetting hideSimilarMaxMessagesToCheck = {
|
||||
"/similarity/hideSimilarMaxMessagesToCheck", 3};
|
||||
|
||||
private:
|
||||
void updateModerationActions();
|
||||
};
|
||||
|
|
|
@ -351,6 +351,11 @@ void Window::addShortcuts()
|
|||
getApp()->twitch.server->getOrAddChannel(si.channelName));
|
||||
splitContainer->appendSplit(split);
|
||||
});
|
||||
|
||||
createWindowShortcut(this, "CTRL+H", [this] {
|
||||
getSettings()->hideSimilar.setValue(!getSettings()->hideSimilar);
|
||||
getApp()->windows->forceLayoutChannelViews();
|
||||
});
|
||||
}
|
||||
|
||||
void Window::addMenuBar()
|
||||
|
|
|
@ -547,6 +547,33 @@ void GeneralPage::initLayout(SettingsLayout &layout)
|
|||
QDesktopServices::openUrl(getPaths()->rootAppDataDirectory);
|
||||
});
|
||||
|
||||
layout.addTitle("Similarity");
|
||||
layout.addDescription(
|
||||
"Hides or grays out similar messages from the same user");
|
||||
layout.addCheckbox("Similarity enabled", s.similarityEnabled);
|
||||
layout.addCheckbox("Gray out similar messages", s.colorSimilarDisabled);
|
||||
layout.addCheckbox("Hide similar messages (Ctrl + H)", s.hideSimilar);
|
||||
layout.addCheckbox("Hide or gray out my own similar messages",
|
||||
s.hideSimilarMyself);
|
||||
layout.addCheckbox("Shown similar messages trigger highlights",
|
||||
s.shownSimilarTriggerHighlights);
|
||||
layout.addDropdown<float>(
|
||||
"Similarity percentage", {"0.5", "0.75", "0.9"}, s.similarityPercentage,
|
||||
[](auto val) { return QString::number(val); },
|
||||
[](auto args) { return fuzzyToFloat(args.value, 0.9f); });
|
||||
s.hideSimilar.connect(
|
||||
[]() { getApp()->windows->forceLayoutChannelViews(); }, false);
|
||||
layout.addDropdown<int>(
|
||||
"Similar messages max delay in seconds",
|
||||
{"5", "10", "15", "30", "60", "120"}, s.hideSimilarMaxDelay,
|
||||
[](auto val) { return QString::number(val); },
|
||||
[](auto args) { return fuzzyToInt(args.value, 5); });
|
||||
layout.addDropdown<int>(
|
||||
"Similar messages max previous messages to check",
|
||||
{"1", "2", "3", "4", "5"}, s.hideSimilarMaxMessagesToCheck,
|
||||
[](auto val) { return QString::number(val); },
|
||||
[](auto args) { return fuzzyToInt(args.value, 3); });
|
||||
|
||||
// invisible element for width
|
||||
auto inv = new BaseWidget(this);
|
||||
inv->setScaleIndependantWidth(500);
|
||||
|
|
|
@ -26,6 +26,10 @@ KeyboardSettingsPage::KeyboardSettingsPage()
|
|||
form->addRow(new QLabel("Ctrl + Shift + T"), new QLabel("Create new tab"));
|
||||
form->addRow(new QLabel("Ctrl + Shift + W"),
|
||||
new QLabel("Close current tab"));
|
||||
form->addRow(
|
||||
new QLabel("Ctrl + H"),
|
||||
new QLabel(
|
||||
"Hide/Show similar messages (Enable in General under Similarity)"));
|
||||
|
||||
form->addItem(new QSpacerItem(16, 16));
|
||||
form->addRow(new QLabel("Ctrl + 1/2/3/..."),
|
||||
|
|
Loading…
Reference in a new issue