feat(eventsub): implement timeout stacking (#6013)

This commit is contained in:
nerix
2025-03-01 23:04:30 +01:00
committed by GitHub
parent 1332743716
commit 7ad3e50a94
12 changed files with 2334 additions and 76 deletions
+30 -11
View File
@@ -630,7 +630,8 @@ MessagePtrMut MessageBuilder::makeSubgiftMessage(const QString &text,
MessageBuilder::MessageBuilder(TimeoutMessageTag, const QString &timeoutUser,
const QString &sourceUser,
const QString &systemMessageText, int times,
const QString &channel,
const QString &systemMessageText, uint32_t times,
const QDateTime &time)
: MessageBuilder()
{
@@ -645,20 +646,38 @@ MessageBuilder::MessageBuilder(TimeoutMessageTag, const QString &timeoutUser,
->setLink(
{Link::UserInfo, timeoutUserIsFirst ? timeoutUser : sourceUser});
auto appendUser = [&](const QString &name) {
auto pos = remainder.indexOf(name);
if (pos > 0)
{
QString start = remainder.mid(0, pos - 1);
remainder = remainder.mid(pos + name.length());
this->emplaceSystemTextAndUpdate(start, messageText);
auto *el = this->emplaceSystemTextAndUpdate(name, messageText)
->setLink({Link::UserInfo, name});
if (remainder.startsWith(' '))
{
remainder.removeFirst();
}
else
{
assert(messageText.endsWith(' '));
messageText.removeLast();
el->setTrailingSpace(false);
}
}
};
if (!sourceUser.isEmpty())
{
// the second username in the message
const auto &targetUsername =
timeoutUserIsFirst ? sourceUser : timeoutUser;
int userPos = remainder.indexOf(targetUsername);
appendUser(timeoutUserIsFirst ? sourceUser : timeoutUser);
}
QString mid = remainder.mid(0, userPos - 1);
QString username = remainder.mid(userPos, targetUsername.length());
remainder = remainder.mid(userPos + targetUsername.length() + 1);
this->emplaceSystemTextAndUpdate(mid, messageText);
this->emplaceSystemTextAndUpdate(username, messageText)
->setLink({Link::UserInfo, username});
if (!channel.isEmpty())
{
appendUser(channel);
}
this->emplaceSystemTextAndUpdate(
+3 -2
View File
@@ -107,8 +107,9 @@ public:
MessageBuilder(SystemMessageTag, const QString &text,
const QTime &time = QTime::currentTime());
MessageBuilder(TimeoutMessageTag, const QString &timeoutUser,
const QString &sourceUser, const QString &systemMessageText,
int times, const QDateTime &time);
const QString &sourceUser, const QString &channel,
const QString &systemMessageText, uint32_t times,
const QDateTime &time);
MessageBuilder(TimeoutMessageTag, const QString &username,
const QString &durationInSeconds, bool multipleTimes,
const QDateTime &time);
@@ -43,13 +43,21 @@ void handleModerateMessage(
EventSubMessageBuilder builder(chan, time);
builder->loginName = event.moderatorUserLogin.qt();
// pretend we're pubsub
builder->flags.set(MessageFlag::PubSub);
QString text;
bool isShared = event.isFromSharedChat();
builder.appendUser(event.moderatorUserName, event.moderatorUserLogin, text);
// XXX: We use regular links here instead of appendUser, because stacking
// will create those as well. Once everything uses mention elements,
// this can use them as well.
builder.emplaceSystemTextAndUpdate(event.moderatorUserLogin.qt(), text)
->setLink({Link::UserInfo, event.moderatorUserLogin.qt()});
builder.emplaceSystemTextAndUpdate("timed out", text);
builder.appendUser(action.userName, action.userLogin, text);
builder.emplaceSystemTextAndUpdate(action.userLogin.qt(), text)
->setLink({Link::UserInfo, action.userLogin.qt()});
builder.emplaceSystemTextAndUpdate("for", text);
builder
@@ -60,10 +68,18 @@ void handleModerateMessage(
if (isShared)
{
builder.emplaceSystemTextAndUpdate("in", text);
builder.appendUser(*event.sourceBroadcasterUserName,
*event.sourceBroadcasterUserLogin, text, false);
builder
.emplaceSystemTextAndUpdate(event.sourceBroadcasterUserLogin->qt(),
text)
->setLink({Link::UserInfo, event.sourceBroadcasterUserLogin->qt()})
->setTrailingSpace(false);
builder->flags.set(MessageFlag::SharedMessage);
builder->channelName = event.sourceBroadcasterUserLogin->qt();
}
assert(text.endsWith(' '));
text.removeLast(); // trailing space
if (action.reason.view().empty())
{
builder.emplaceSystemTextAndUpdate(".", text);
@@ -79,9 +95,8 @@ void handleModerateMessage(
builder->timeoutUser = action.userLogin.qt();
auto msg = builder.release();
runInGuiThread([chan, msg] {
// TODO: addOrReplaceTimeout (doesn't work with shared chat yet)
chan->addMessage(msg, MessageContext::Original);
runInGuiThread([chan, msg, time] {
chan->addOrReplaceTimeout(msg, time);
});
}
+12 -7
View File
@@ -52,11 +52,6 @@ void addOrReplaceChannelTimeout(const Buf &buffer, MessagePtr message,
break;
}
if (s->flags.has(MessageFlag::EventSub))
{
continue; // TODO: implement stacking for eventsub
}
if (timeoutStackStyle == TimeoutStackStyle::DontStackBeyondUserMessage)
{
if (s->loginName == message->timeoutUser &&
@@ -67,6 +62,14 @@ void addOrReplaceChannelTimeout(const Buf &buffer, MessagePtr message,
}
}
bool newIsShared = message->flags.has(MessageFlag::SharedMessage);
bool oldIsShared = s->flags.has(MessageFlag::SharedMessage);
if (newIsShared != oldIsShared ||
(newIsShared && message->channelName != s->channelName))
{
continue;
}
if (s->flags.has(MessageFlag::Timeout) &&
s->timeoutUser == message->timeoutUser)
{
@@ -88,10 +91,12 @@ void addOrReplaceChannelTimeout(const Buf &buffer, MessagePtr message,
uint32_t count = s->count + 1;
MessageBuilder replacement(timeoutMessage, message->timeoutUser,
message->loginName, message->searchText,
count, message->serverReceivedTime);
message->loginName, message->channelName,
message->searchText, count,
message->serverReceivedTime);
replacement->timeoutUser = message->timeoutUser;
replacement->channelName = message->channelName;
replacement->count = count;
replacement->flags = message->flags;