Show historic timeouts and bans in usercard (#4760)
Co-authored-by: Rasmus Karlsson <rasmus.karlsson@pajlada.com>
This commit is contained in:
@@ -20,52 +20,6 @@ const auto &LOG = chatterinoRecentMessages;
|
||||
|
||||
namespace chatterino::recentmessages::detail {
|
||||
|
||||
// convertClearchatToNotice takes a Communi::IrcMessage that is a CLEARCHAT
|
||||
// command and converts it to a readable NOTICE message. This has
|
||||
// historically been done in the Recent Messages API, but this functionality
|
||||
// has been moved to Chatterino instead.
|
||||
Communi::IrcMessage *convertClearchatToNotice(Communi::IrcMessage *message)
|
||||
{
|
||||
auto channelName = message->parameter(0);
|
||||
QString noticeMessage{};
|
||||
if (message->tags().contains("target-user-id"))
|
||||
{
|
||||
auto target = message->parameter(1);
|
||||
|
||||
if (message->tags().contains("ban-duration"))
|
||||
{
|
||||
// User was timed out
|
||||
noticeMessage =
|
||||
QString("%1 has been timed out for %2.")
|
||||
.arg(target)
|
||||
.arg(formatTime(message->tag("ban-duration").toString()));
|
||||
}
|
||||
else
|
||||
{
|
||||
// User was permanently banned
|
||||
noticeMessage =
|
||||
QString("%1 has been permanently banned.").arg(target);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Chat was cleared
|
||||
noticeMessage = "Chat has been cleared by a moderator.";
|
||||
}
|
||||
|
||||
// rebuild the raw IRC message so we can convert it back to an ircmessage again!
|
||||
// this could probably be done in a smarter way
|
||||
|
||||
auto s = QString(":tmi.twitch.tv NOTICE %1 :%2")
|
||||
.arg(channelName)
|
||||
.arg(noticeMessage);
|
||||
|
||||
auto *newMessage = Communi::IrcMessage::fromData(s.toUtf8(), nullptr);
|
||||
newMessage->setTags(message->tags());
|
||||
|
||||
return newMessage;
|
||||
}
|
||||
|
||||
// Parse the IRC messages returned in JSON form into Communi messages
|
||||
std::vector<Communi::IrcMessage *> parseRecentMessages(
|
||||
const QJsonObject &jsonRoot)
|
||||
@@ -89,11 +43,6 @@ std::vector<Communi::IrcMessage *> parseRecentMessages(
|
||||
auto *message =
|
||||
Communi::IrcMessage::fromData(content.toUtf8(), nullptr);
|
||||
|
||||
if (message->command() == "CLEARCHAT")
|
||||
{
|
||||
message = convertClearchatToNotice(message);
|
||||
}
|
||||
|
||||
messages.emplace_back(message);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,12 +13,6 @@
|
||||
|
||||
namespace chatterino::recentmessages::detail {
|
||||
|
||||
// convertClearchatToNotice takes a Communi::IrcMessage that is a CLEARCHAT
|
||||
// command and converts it to a readable NOTICE message. This has
|
||||
// historically been done in the Recent Messages API, but this functionality
|
||||
// has been moved to Chatterino instead.
|
||||
Communi::IrcMessage *convertClearchatToNotice(Communi::IrcMessage *message);
|
||||
|
||||
// Parse the IRC messages returned in JSON form into Communi messages
|
||||
std::vector<Communi::IrcMessage *> parseRecentMessages(
|
||||
const QJsonObject &jsonRoot);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "IrcMessageHandler.hpp"
|
||||
#include "providers/twitch/IrcMessageHandler.hpp"
|
||||
|
||||
#include "Application.hpp"
|
||||
#include "common/Literals.hpp"
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "singletons/Resources.hpp"
|
||||
#include "singletons/Settings.hpp"
|
||||
#include "singletons/WindowManager.hpp"
|
||||
#include "util/ChannelHelpers.hpp"
|
||||
#include "util/FormatTime.hpp"
|
||||
#include "util/Helpers.hpp"
|
||||
#include "util/IrcHelpers.hpp"
|
||||
@@ -377,7 +378,7 @@ void IrcMessageHandler::handlePrivMessage(Communi::IrcPrivateMessage *message,
|
||||
|
||||
std::vector<MessagePtr> IrcMessageHandler::parseMessageWithReply(
|
||||
Channel *channel, Communi::IrcMessage *message,
|
||||
const std::vector<MessagePtr> &otherLoaded)
|
||||
std::vector<MessagePtr> &otherLoaded)
|
||||
{
|
||||
std::vector<MessagePtr> builtMessages;
|
||||
|
||||
@@ -416,6 +417,33 @@ std::vector<MessagePtr> IrcMessageHandler::parseMessageWithReply(
|
||||
return this->parseNoticeMessage(
|
||||
static_cast<Communi::IrcNoticeMessage *>(message));
|
||||
}
|
||||
else if (command == u"CLEARCHAT"_s)
|
||||
{
|
||||
auto cc = this->parseClearChatMessage(message);
|
||||
if (!cc)
|
||||
{
|
||||
return builtMessages;
|
||||
}
|
||||
auto &clearChat = *cc;
|
||||
if (clearChat.disableAllMessages)
|
||||
{
|
||||
builtMessages.emplace_back(std::move(clearChat.message));
|
||||
}
|
||||
else
|
||||
{
|
||||
addOrReplaceChannelTimeout(
|
||||
otherLoaded, std::move(clearChat.message),
|
||||
calculateMessageTime(message).time(),
|
||||
[&](auto idx, auto /*msg*/, auto &&replacement) {
|
||||
replacement->flags.set(MessageFlag::RecentMessage);
|
||||
otherLoaded[idx] = replacement;
|
||||
},
|
||||
[&](auto &&msg) {
|
||||
builtMessages.emplace_back(msg);
|
||||
},
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
return builtMessages;
|
||||
}
|
||||
@@ -662,40 +690,24 @@ void IrcMessageHandler::handleRoomStateMessage(Communi::IrcMessage *message)
|
||||
twitchChannel->roomModesChanged.invoke();
|
||||
}
|
||||
|
||||
void IrcMessageHandler::handleClearChatMessage(Communi::IrcMessage *message)
|
||||
std::optional<ClearChatMessage> IrcMessageHandler::parseClearChatMessage(
|
||||
Communi::IrcMessage *message)
|
||||
{
|
||||
// check parameter count
|
||||
if (message->parameters().length() < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QString chanName;
|
||||
if (!trimChannelName(message->parameter(0), chanName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// get channel
|
||||
auto chan = getApp()->twitch->getChannelOrEmpty(chanName);
|
||||
|
||||
if (chan->isEmpty())
|
||||
{
|
||||
qCDebug(chatterinoTwitch)
|
||||
<< "[IrcMessageHandler:handleClearChatMessage] Twitch channel"
|
||||
<< chanName << "not found";
|
||||
return;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// check if the chat has been cleared by a moderator
|
||||
if (message->parameters().length() == 1)
|
||||
{
|
||||
chan->disableAllMessages();
|
||||
chan->addMessage(
|
||||
makeSystemMessage("Chat has been cleared by a moderator.",
|
||||
calculateMessageTime(message).time()));
|
||||
|
||||
return;
|
||||
return ClearChatMessage{
|
||||
.message =
|
||||
makeSystemMessage("Chat has been cleared by a moderator.",
|
||||
calculateMessageTime(message).time()),
|
||||
.disableAllMessages = true,
|
||||
};
|
||||
}
|
||||
|
||||
// get username, duration and message of the timed out user
|
||||
@@ -711,7 +723,46 @@ void IrcMessageHandler::handleClearChatMessage(Communi::IrcMessage *message)
|
||||
MessageBuilder(timeoutMessage, username, durationInSeconds, false,
|
||||
calculateMessageTime(message).time())
|
||||
.release();
|
||||
chan->addOrReplaceTimeout(timeoutMsg);
|
||||
|
||||
return ClearChatMessage{.message = timeoutMsg, .disableAllMessages = false};
|
||||
}
|
||||
|
||||
void IrcMessageHandler::handleClearChatMessage(Communi::IrcMessage *message)
|
||||
{
|
||||
auto cc = this->parseClearChatMessage(message);
|
||||
if (!cc)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto &clearChat = *cc;
|
||||
|
||||
QString chanName;
|
||||
if (!trimChannelName(message->parameter(0), chanName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// get channel
|
||||
auto chan = getApp()->twitch->getChannelOrEmpty(chanName);
|
||||
|
||||
if (chan->isEmpty())
|
||||
{
|
||||
qCDebug(chatterinoTwitch)
|
||||
<< "[IrcMessageHandler::handleClearChatMessage] Twitch channel"
|
||||
<< chanName << "not found";
|
||||
return;
|
||||
}
|
||||
|
||||
// chat has been cleared by a moderator
|
||||
if (clearChat.disableAllMessages)
|
||||
{
|
||||
chan->disableAllMessages();
|
||||
chan->addMessage(std::move(clearChat.message));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
chan->addOrReplaceTimeout(std::move(clearChat.message));
|
||||
|
||||
// refresh all
|
||||
getApp()->windows->repaintVisibleChatWidgets(chan.get());
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <IrcMessage>
|
||||
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
namespace chatterino {
|
||||
@@ -16,6 +17,11 @@ using MessagePtr = std::shared_ptr<const Message>;
|
||||
class TwitchChannel;
|
||||
class TwitchMessageBuilder;
|
||||
|
||||
struct ClearChatMessage {
|
||||
MessagePtr message;
|
||||
bool disableAllMessages;
|
||||
};
|
||||
|
||||
class IrcMessageHandler
|
||||
{
|
||||
IrcMessageHandler() = default;
|
||||
@@ -29,7 +35,7 @@ public:
|
||||
|
||||
std::vector<MessagePtr> parseMessageWithReply(
|
||||
Channel *channel, Communi::IrcMessage *message,
|
||||
const std::vector<MessagePtr> &otherLoaded);
|
||||
std::vector<MessagePtr> &otherLoaded);
|
||||
|
||||
// parsePrivMessage arses a single IRC PRIVMSG into 0-1 Chatterino messages
|
||||
std::vector<MessagePtr> parsePrivMessage(
|
||||
@@ -38,6 +44,8 @@ public:
|
||||
TwitchIrcServer &server);
|
||||
|
||||
void handleRoomStateMessage(Communi::IrcMessage *message);
|
||||
std::optional<ClearChatMessage> parseClearChatMessage(
|
||||
Communi::IrcMessage *message);
|
||||
void handleClearChatMessage(Communi::IrcMessage *message);
|
||||
void handleClearMessageMessage(Communi::IrcMessage *message);
|
||||
void handleUserStateMessage(Communi::IrcMessage *message);
|
||||
|
||||
Reference in New Issue
Block a user