refactor(eventsub): Respect "Hide moderation actions" explicitly (#6041)

This commit is contained in:
pajlada
2025-03-08 14:00:35 +01:00
committed by GitHub
parent 0835064375
commit 77c4d858f9
79 changed files with 153 additions and 125 deletions
+9 -7
View File
@@ -729,6 +729,7 @@ MessageBuilder::MessageBuilder(TimeoutMessageTag, const QString &username,
this->message().flags.set(MessageFlag::System);
this->message().flags.set(MessageFlag::Timeout);
this->message().flags.set(MessageFlag::ModerationAction);
this->message().flags.set(MessageFlag::DoNotTriggerNotification);
this->message().timeoutUser = username;
@@ -747,6 +748,7 @@ MessageBuilder::MessageBuilder(const BanAction &action, const QDateTime &time,
this->emplace<TimestampElement>();
this->message().flags.set(MessageFlag::System);
this->message().flags.set(MessageFlag::Timeout);
this->message().flags.set(MessageFlag::ModerationAction);
this->message().timeoutUser = action.target.login;
this->message().loginName = action.source.login;
this->message().count = count;
@@ -1464,7 +1466,7 @@ MessagePtr MessageBuilder::makeDeletionMessageFromIRC(
builder.emplace<TimestampElement>();
builder.message().flags.set(MessageFlag::System);
builder.message().flags.set(MessageFlag::DoNotTriggerNotification);
builder.message().flags.set(MessageFlag::Timeout);
builder.message().flags.set(MessageFlag::ModerationAction);
// TODO(mm2pl): If or when jumping to a single message gets implemented a link,
// add a link to the originalMessage
builder.emplace<TextElement>("A message from", MessageElementFlag::Text,
@@ -1503,7 +1505,7 @@ MessagePtr MessageBuilder::makeDeletionMessageFromPubSub(
builder.emplace<TimestampElement>();
builder.message().flags.set(MessageFlag::System);
builder.message().flags.set(MessageFlag::DoNotTriggerNotification);
builder.message().flags.set(MessageFlag::Timeout);
builder.message().flags.set(MessageFlag::ModerationAction);
builder
.emplace<TextElement>(action.source.login, MessageElementFlag::Username,
@@ -1710,7 +1712,7 @@ std::pair<MessagePtr, MessagePtr> MessageBuilder::makeAutomodMessage(
builder.message().loginName = "automod";
builder.message().channelName = channelName;
builder.message().flags.set(MessageFlag::PubSub);
builder.message().flags.set(MessageFlag::Timeout);
builder.message().flags.set(MessageFlag::ModerationAction);
builder.message().flags.set(MessageFlag::AutoMod);
builder.message().flags.set(MessageFlag::AutoModOffendingMessageHeader);
@@ -1761,7 +1763,7 @@ std::pair<MessagePtr, MessagePtr> MessageBuilder::makeAutomodMessage(
builder2.emplace<TwitchModerationElement>();
builder2.message().loginName = action.target.login;
builder2.message().flags.set(MessageFlag::PubSub);
builder2.message().flags.set(MessageFlag::Timeout);
builder2.message().flags.set(MessageFlag::ModerationAction);
builder2.message().flags.set(MessageFlag::AutoMod);
builder2.message().flags.set(MessageFlag::AutoModOffendingMessage);
@@ -2063,9 +2065,9 @@ MessagePtrMut MessageBuilder::makeClearChatMessage(const QDateTime &now,
builder.emplace<TimestampElement>(now.time());
builder->count = count;
builder->serverReceivedTime = now;
builder.message().flags.set(MessageFlag::System,
MessageFlag::DoNotTriggerNotification,
MessageFlag::ClearChat);
builder.message().flags.set(
MessageFlag::System, MessageFlag::DoNotTriggerNotification,
MessageFlag::ClearChat, MessageFlag::ModerationAction);
QString messageText;
if (actor.isEmpty())
+7
View File
@@ -58,6 +58,13 @@ enum class MessageFlag : std::int64_t {
ClearChat = (1LL << 39),
/// The message is built from EventSub
EventSub = (1LL << 40),
/// The message is a moderation action.
/// Example messages that would count as moderation actions:
/// - forsen has been banned
/// - forsen deleted message from forsen
/// - forsen added "blockedterm" as a blocked term
/// - Your message is being checked by mods and has not been sent
ModerationAction = (1LL << 41),
};
using MessageFlags = FlagsEnum<MessageFlag>;
+7 -8
View File
@@ -166,16 +166,14 @@ void MessageLayout::actuallyLayout(const MessageLayoutContext &ctx)
continue;
}
if (this->message_->flags.has(MessageFlag::Timeout) ||
this->message_->flags.has(MessageFlag::Untimeout))
if (this->message_->flags.has(MessageFlag::ModerationAction))
{
// NOTE: This hides the message but it will make the message re-appear if moderation message hiding is no longer active, and the layout is re-laid-out.
// This is only the case for the moderation messages that don't get filtered during creation.
// We should decide which is the correct method & apply that everywhere
if (hideModerationActions ||
(getSettings()->streamerModeHideModActions &&
getApp()->getStreamerMode()->isEnabled()))
getApp()->getStreamerMode()->shouldHideModActions())
{
// Message is being hidden because we consider the message
// a moderation action (something a streamer is unlikely to
// want to share if they briefly show their chat on stream)
continue;
}
}
@@ -515,7 +513,8 @@ bool MessageLayout::isReplyable() const
if (this->message_->flags.hasAny(
{MessageFlag::System, MessageFlag::Subscription,
MessageFlag::Timeout, MessageFlag::Whisper}))
MessageFlag::Timeout, MessageFlag::Whisper,
MessageFlag::ModerationAction}))
{
return false;
}
+9 -6
View File
@@ -431,9 +431,10 @@ void TwitchIrcServer::initialize()
return;
}
if (getSettings()->streamerModeHideModActions &&
getApp()->getStreamerMode()->isEnabled())
if (getApp()->getStreamerMode()->shouldHideModActions())
{
// NOTE: This completely stops the building of this action, rathern than only hiding it.
// If the user disabled streamer mode or the setting, there will be messages missing
return;
}
@@ -476,9 +477,10 @@ void TwitchIrcServer::initialize()
return;
}
if (getSettings()->streamerModeHideModActions &&
getApp()->getStreamerMode()->isEnabled())
if (getApp()->getStreamerMode()->shouldHideModActions())
{
// NOTE: This completely stops the building of this action, rathern than only hiding it.
// If the user disabled streamer mode or the setting, there will be messages missing
return;
}
@@ -680,9 +682,10 @@ void TwitchIrcServer::initialize()
this->connections_.managedConnect(
getApp()->getTwitchPubSub()->moderation.automodUserMessage,
[this](const auto &action) {
if (getSettings()->streamerModeHideModActions &&
getApp()->getStreamerMode()->isEnabled())
if (getApp()->getStreamerMode()->shouldHideModActions())
{
// NOTE: This completely stops the building of this action, rathern than only hiding it.
// If the user disabled streamer mode or the setting, there will be messages missing
return;
}
auto chan = this->getChannelOrEmptyByID(action.roomID);
@@ -281,12 +281,6 @@ void Connection::onChannelSuspiciousUserMessage(
return;
}
if (getSettings()->streamerModeHideModActions &&
getApp()->getStreamerMode()->isEnabled())
{
return;
}
auto *channel = dynamic_cast<TwitchChannel *>(
getApp()
->getTwitch()
@@ -143,7 +143,6 @@ EventSubMessageBuilder::EventSubMessageBuilder(TwitchChannel *channel,
{
this->emplace<TimestampElement>(time.time());
this->message().flags.set(MessageFlag::System, MessageFlag::EventSub);
this->message().flags.set(MessageFlag::Timeout); // do we need this?
this->message().serverReceivedTime = time;
}
@@ -217,6 +216,7 @@ void makeModerateMessage(EventSubMessageBuilder &builder,
const lib::payload::channel_moderate::v2::Event &event,
const lib::payload::channel_moderate::v2::Warn &action)
{
builder->flags.set(MessageFlag::ModerationAction);
QString text;
builder.appendUser(event.moderatorUserName, event.moderatorUserLogin, text);
@@ -255,6 +255,8 @@ void makeModerateMessage(EventSubMessageBuilder &builder,
const lib::payload::channel_moderate::v2::Event &event,
const lib::payload::channel_moderate::v2::Ban &action)
{
builder->flags.set(MessageFlag::ModerationAction, MessageFlag::Timeout);
QString text;
bool isShared = event.isFromSharedChat();
@@ -288,6 +290,8 @@ void makeModerateMessage(
const lib::payload::channel_moderate::v2::Event &event,
const lib::payload::channel_moderate::v2::Unban &action)
{
builder->flags.set(MessageFlag::ModerationAction, MessageFlag::Untimeout);
QString text;
bool isShared = event.isFromSharedChat();
@@ -313,10 +317,11 @@ void makeModerateMessage(
const lib::payload::channel_moderate::v2::Event &event,
const lib::payload::channel_moderate::v2::Untimeout &action)
{
builder->flags.set(MessageFlag::ModerationAction, MessageFlag::Untimeout);
QString text;
bool isShared = event.isFromSharedChat();
builder->flags.set(MessageFlag::Timeout);
builder.appendUser(event.moderatorUserName, event.moderatorUserLogin, text);
builder.emplaceSystemTextAndUpdate("untimedout", text);
builder.appendUser(action.userName, action.userLogin, text, isShared);
@@ -339,7 +344,8 @@ void makeModerateMessage(
const lib::payload::channel_moderate::v2::Event &event,
const lib::payload::channel_moderate::v2::Delete &action)
{
builder.message().flags.set(MessageFlag::DoNotTriggerNotification);
builder->flags.set(MessageFlag::DoNotTriggerNotification,
MessageFlag::ModerationAction);
QString text;
bool isShared = event.isFromSharedChat();
@@ -465,6 +471,8 @@ void makeModerateMessage(
const lib::payload::channel_moderate::v2::Event &event,
const lib::payload::channel_moderate::v2::AutomodTerms &action)
{
builder->flags.set(MessageFlag::ModerationAction);
QString text;
builder.appendUser(event.moderatorUserName, event.moderatorUserLogin, text);
@@ -589,7 +597,7 @@ MessagePtr makeAutomodHoldMessageHeader(
builder->id = u"automod_" % event.messageID.qt();
builder->loginName = u"automod"_s;
builder->channelName = event.broadcasterUserLogin.qt();
builder->flags.set(MessageFlag::PubSub, MessageFlag::Timeout,
builder->flags.set(MessageFlag::PubSub, MessageFlag::ModerationAction,
MessageFlag::AutoMod,
MessageFlag::AutoModOffendingMessageHeader);
builder->flags.set(
@@ -637,7 +645,7 @@ MessagePtr makeAutomodHoldMessageBody(
{
EventSubMessageBuilder builder(channel);
builder->serverReceivedTime = time;
builder->flags.set(MessageFlag::PubSub, MessageFlag::Timeout,
builder->flags.set(MessageFlag::PubSub, MessageFlag::ModerationAction,
MessageFlag::AutoMod,
MessageFlag::AutoModOffendingMessage);
builder->flags.set(
@@ -784,7 +792,8 @@ MessagePtr makeSuspiciousUserUpdate(
const lib::payload::channel_suspicious_user_update::v1::Event &event)
{
EventSubMessageBuilder builder(channel, time);
builder->flags.set(MessageFlag::DoNotTriggerNotification);
builder->flags.set(MessageFlag::DoNotTriggerNotification,
MessageFlag::ModerationAction);
builder->loginName = event.moderatorUserLogin.qt();
QString text;
@@ -833,8 +842,7 @@ MessagePtr makeUserMessageHeldMessage(
builder->id = u"automod_" % event.messageID.qt();
builder->loginName = u"automod"_s;
builder->channelName = event.broadcasterUserLogin.qt();
builder->flags.set(MessageFlag::PubSub, MessageFlag::Timeout,
MessageFlag::AutoMod);
builder->flags.set(MessageFlag::PubSub, MessageFlag::AutoMod);
// AutoMod shield badge
builder.emplace<BadgeElement>(makeAutoModBadge(),
@@ -863,8 +871,7 @@ MessagePtr makeUserMessageUpdateMessage(
builder->id = u"automod_" % event.messageID.qt();
builder->loginName = u"automod"_s;
builder->channelName = event.broadcasterUserLogin.qt();
builder->flags.set(MessageFlag::PubSub, MessageFlag::Timeout,
MessageFlag::AutoMod);
builder->flags.set(MessageFlag::PubSub, MessageFlag::AutoMod);
// AutoMod shield badge
builder.emplace<BadgeElement>(makeAutoModBadge(),
@@ -45,7 +45,8 @@ void handleModerateMessage(
EventSubMessageBuilder builder(chan, time);
builder->loginName = event.moderatorUserLogin.qt();
// pretend we're pubsub
builder->flags.set(MessageFlag::PubSub);
builder->flags.set(MessageFlag::PubSub, MessageFlag::Timeout,
MessageFlag::ModerationAction);
QString text;
bool isShared = event.isFromSharedChat();
+5
View File
@@ -202,6 +202,11 @@ bool StreamerMode::isEnabled() const
return this->private_->isEnabled();
}
bool StreamerMode::shouldHideModActions() const
{
return getSettings()->streamerModeHideModActions && this->isEnabled();
}
void StreamerMode::start()
{
this->private_->start();
+5
View File
@@ -20,6 +20,9 @@ public:
[[nodiscard]] virtual bool isEnabled() const = 0;
/// Returns true if streamer mode is enabled & the settings to hide mod actions is enabled
[[nodiscard]] virtual bool shouldHideModActions() const = 0;
virtual void start() = 0;
Q_SIGNALS:
@@ -39,6 +42,8 @@ public:
bool isEnabled() const override;
bool shouldHideModActions() const override;
void start() override;
private:
+4 -4
View File
@@ -55,8 +55,8 @@ void addOrReplaceChannelTimeout(const Buf &buffer, MessagePtr message,
if (timeoutStackStyle == TimeoutStackStyle::DontStackBeyondUserMessage)
{
if (s->loginName == message->timeoutUser &&
s->flags.hasNone({MessageFlag::Disabled, MessageFlag::Timeout,
MessageFlag::Untimeout}))
s->flags.hasNone(
{MessageFlag::Disabled, MessageFlag::ModerationAction}))
{
break;
}
@@ -114,8 +114,8 @@ void addOrReplaceChannelTimeout(const Buf &buffer, MessagePtr message,
{
auto &s = buffer[i];
if (s->loginName == message->timeoutUser &&
s->flags.hasNone({MessageFlag::Timeout, MessageFlag::Untimeout,
MessageFlag::Whisper}))
s->flags.hasNone(
{MessageFlag::ModerationAction, MessageFlag::Whisper}))
{
// FOURTF: disabled for now
// PAJLADA: Shitty solution described in Message.hpp