feat(eventsub): implement clearchat (#5981)

This commit is contained in:
nerix
2025-02-23 21:28:26 +01:00
committed by GitHub
parent c67801eca5
commit 5fca241188
8 changed files with 199 additions and 7 deletions
+1 -1
View File
@@ -30,7 +30,7 @@
- Bugfix: Fixed the input font not immediately updating when zooming in/out. (#5960)
- Bugfix: Fixed color input thinking blue is also red. (#5982)
- Dev: Subscriptions to PubSub channel points redemption topics now use no auth token, making it continue to work during PubSub shutdown. (#5947)
- Dev: Add initial experimental EventSub support. (#5837, #5895, #5897, #5904, #5910, #5903, #5915, #5916, #5930, #5935, #5932, #5943, #5952, #5953, #5968, #5973, #5974, #5980)
- Dev: Add initial experimental EventSub support. (#5837, #5895, #5897, #5904, #5910, #5903, #5915, #5916, #5930, #5935, #5932, #5943, #5952, #5953, #5968, #5973, #5974, #5980, #5981)
- Dev: Remove unneeded platform specifier for toasts. (#5914)
- Dev: Highlight checks now use non-capturing groups for the boundaries. (#5784)
- Dev: Removed unused PubSub whisper code. (#5898)
-2
View File
@@ -502,8 +502,6 @@ Updates &Application::getUpdates()
ITwitchIrcServer *Application::getTwitch()
{
assertInGuiThread();
return this->twitch.get();
}
+2
View File
@@ -434,6 +434,8 @@ set(SOURCE_FILES
providers/twitch/eventsub/Controller.hpp
providers/twitch/eventsub/MessageBuilder.cpp
providers/twitch/eventsub/MessageBuilder.hpp
providers/twitch/eventsub/MessageHandlers.cpp
providers/twitch/eventsub/MessageHandlers.hpp
providers/twitch/eventsub/SubscriptionHandle.cpp
providers/twitch/eventsub/SubscriptionHandle.hpp
providers/twitch/eventsub/SubscriptionRequest.cpp
+8
View File
@@ -1303,6 +1303,8 @@ const IndirectChannel &TwitchIrcServer::getWatchingChannel() const
void TwitchIrcServer::setWatchingChannel(ChannelPtr newWatchingChannel)
{
assertInGuiThread();
this->watchingChannel.reset(newWatchingChannel);
}
@@ -1333,6 +1335,8 @@ QString TwitchIrcServer::getLastUserThatWhisperedMe() const
void TwitchIrcServer::setLastUserThatWhisperedMe(const QString &user)
{
assertInGuiThread();
this->lastUserThatWhisperedMe.set(user);
}
@@ -1451,6 +1455,8 @@ void TwitchIrcServer::markChannelsConnected()
void TwitchIrcServer::addFakeMessage(const QString &data)
{
assertInGuiThread();
auto *fakeMessage = Communi::IrcMessage::fromData(
data.toUtf8(), this->readConnection_.get());
@@ -1502,6 +1508,8 @@ void TwitchIrcServer::forEachChannel(std::function<void(ChannelPtr)> func)
void TwitchIrcServer::connect()
{
assertInGuiThread();
this->disconnect();
this->initializeConnection(this->writeConnection_.get(),
+21 -4
View File
@@ -6,9 +6,12 @@
#include "messages/Message.hpp"
#include "messages/MessageBuilder.hpp"
#include "providers/twitch/eventsub/MessageBuilder.hpp"
#include "providers/twitch/eventsub/MessageHandlers.hpp"
#include "providers/twitch/PubSubActions.hpp"
#include "providers/twitch/TwitchChannel.hpp"
#include "providers/twitch/TwitchIrcServer.hpp"
#include "singletons/Settings.hpp"
#include "singletons/WindowManager.hpp"
#include "util/PostToThread.hpp"
#include <boost/json.hpp>
@@ -23,15 +26,24 @@ namespace {
using namespace chatterino;
using namespace chatterino::eventsub;
namespace channel_moderate = lib::payload::channel_moderate::v2;
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
const auto &LOG = chatterinoTwitchEventSub;
template <typename Action>
concept CanMakeModMessage =
requires(EventSubMessageBuilder &builder,
const lib::payload::channel_moderate::v2::Event &event,
concept CanMakeModMessage = requires(
EventSubMessageBuilder &builder, const channel_moderate::Event &event,
const std::remove_cvref_t<Action> &action) {
makeModerateMessage(builder, event, action);
};
template <typename Action>
concept CanHandleModMessage =
requires(TwitchChannel *channel, const QDateTime &time,
const channel_moderate::Event &event,
const std::remove_cvref_t<Action> &action) {
makeModerateMessage(builder, event, action);
handleModerateMessage(channel, time, event, action);
};
} // namespace
@@ -199,6 +211,11 @@ void Connection::onChannelModerate(
channel->addMessage(msg, MessageContext::Original);
});
}
if constexpr (CanHandleModMessage<Action>)
{
handleModerateMessage(channel, now, payload.event, action);
}
},
payload.event.action);
}
@@ -0,0 +1,29 @@
#include "providers/twitch/eventsub/MessageHandlers.hpp"
#include "Application.hpp"
#include "messages/MessageBuilder.hpp"
#include "providers/twitch/TwitchChannel.hpp"
#include "singletons/Settings.hpp"
#include "singletons/WindowManager.hpp"
#include "util/PostToThread.hpp"
namespace chatterino::eventsub {
void handleModerateMessage(
TwitchChannel *chan, const QDateTime &time,
const lib::payload::channel_moderate::v2::Event &event,
const lib::payload::channel_moderate::v2::Clear & /*action*/)
{
runInGuiThread([chan, actor{event.moderatorUserLogin.qt()}, time] {
chan->addOrReplaceClearChat(
MessageBuilder::makeClearChatMessage(time, actor), time);
if (getSettings()->hideModerated)
{
// XXX: This is expensive. We could use a layout request if the layout
// would store the previous message flags.
getApp()->getWindows()->forceLayoutChannelViews();
}
});
}
} // namespace chatterino::eventsub
@@ -0,0 +1,18 @@
#pragma once
#include "twitch-eventsub-ws/payloads/channel-moderate-v2.hpp"
class QDateTime;
namespace chatterino {
class TwitchChannel;
} // namespace chatterino
namespace chatterino::eventsub {
void handleModerateMessage(
TwitchChannel *chan, const QDateTime &time,
const lib::payload::channel_moderate::v2::Event &event,
const lib::payload::channel_moderate::v2::Clear &action);
} // namespace chatterino::eventsub
@@ -0,0 +1,120 @@
{
"input": {
"action": "clear",
"automod_terms": null,
"ban": null,
"broadcaster_user_id": "11148817",
"broadcaster_user_login": "pajlada",
"broadcaster_user_name": "pajlada",
"delete": null,
"followers": null,
"mod": null,
"moderator_user_id": "129546453",
"moderator_user_login": "nerixyz",
"moderator_user_name": "nerixyz",
"raid": null,
"shared_chat_ban": null,
"shared_chat_delete": null,
"shared_chat_timeout": null,
"shared_chat_unban": null,
"shared_chat_untimeout": null,
"slow": null,
"source_broadcaster_user_id": null,
"source_broadcaster_user_login": null,
"source_broadcaster_user_name": null,
"timeout": null,
"unban": null,
"unban_request": null,
"unmod": null,
"unraid": null,
"untimeout": null,
"unvip": null,
"vip": null,
"warn": null
},
"output": [
{
"badgeInfos": {
},
"badges": [
],
"channelName": "",
"count": 1,
"displayName": "",
"elements": [
{
"element": {
"color": "System",
"flags": "Timestamp",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "",
"trailingSpace": true,
"type": "TextElement",
"words": [
"0:00"
]
},
"flags": "Timestamp",
"format": "",
"link": {
"type": "None",
"value": ""
},
"time": "00:00:00",
"tooltip": "",
"trailingSpace": true,
"type": "TimestampElement"
},
{
"color": "Text",
"fallbackColor": "System",
"flags": "Text|Mention",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "",
"trailingSpace": true,
"type": "MentionElement",
"userColor": "System",
"userLoginName": "nerixyz",
"words": [
"nerixyz"
]
},
{
"color": "System",
"flags": "Text",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "",
"trailingSpace": true,
"type": "TextElement",
"words": [
"cleared",
"the",
"chat."
]
}
],
"flags": "System|DoNotTriggerNotification|PubSub|ClearChat",
"id": "",
"localizedName": "",
"loginName": "",
"messageText": "nerixyz cleared the chat. ",
"searchText": "nerixyz cleared the chat. ",
"serverReceivedTime": "1970-01-01T00:00:00Z",
"timeoutUser": "nerixyz",
"userID": "",
"usernameColor": "#ff000000"
}
]
}