mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
Allow moderators to see who deleted a message (#2874)
Co-authored-by: pajlada <rasmus.karlsson@pajlada.com>
This commit is contained in:
parent
f9ddd53037
commit
9640837957
|
@ -12,7 +12,7 @@
|
||||||
- Minor: Limit the number of recent chatters to improve memory usage and reduce freezes. (#2796, #2814)
|
- Minor: Limit the number of recent chatters to improve memory usage and reduce freezes. (#2796, #2814)
|
||||||
- Minor: Added `/popout` command. Usage: `/popout [channel]`. It opens browser chat for the provided channel. Can also be used without arguments to open current channels browser chat. (#2556, #2812)
|
- Minor: Added `/popout` command. Usage: `/popout [channel]`. It opens browser chat for the provided channel. Can also be used without arguments to open current channels browser chat. (#2556, #2812)
|
||||||
- Minor: Improved matching of game names when using `/setgame` command (#2636)
|
- Minor: Improved matching of game names when using `/setgame` command (#2636)
|
||||||
- Minor: Now shows deletions of messages like timeouts (#1155, #2841)
|
- Minor: Now shows deletions of messages like timeouts (#1155, #2841, #2867, #2874)
|
||||||
- Minor: Added a link to accounts page in settings to "You need to be logged in to send messages" message. (#2862)
|
- Minor: Added a link to accounts page in settings to "You need to be logged in to send messages" message. (#2862)
|
||||||
- Minor: Switch to Twitch v2 emote API for animated emote support. (#2863)
|
- Minor: Switch to Twitch v2 emote API for animated emote support. (#2863)
|
||||||
- Bugfix: Fixed FFZ emote links for global emotes (#2807, #2808)
|
- Bugfix: Fixed FFZ emote links for global emotes (#2807, #2808)
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "providers/irc/Irc2.hpp"
|
#include "providers/irc/Irc2.hpp"
|
||||||
#include "providers/twitch/PubsubClient.hpp"
|
#include "providers/twitch/PubsubClient.hpp"
|
||||||
#include "providers/twitch/TwitchIrcServer.hpp"
|
#include "providers/twitch/TwitchIrcServer.hpp"
|
||||||
|
#include "providers/twitch/TwitchMessageBuilder.hpp"
|
||||||
#include "singletons/Emotes.hpp"
|
#include "singletons/Emotes.hpp"
|
||||||
#include "singletons/Fonts.hpp"
|
#include "singletons/Fonts.hpp"
|
||||||
#include "singletons/Logging.hpp"
|
#include "singletons/Logging.hpp"
|
||||||
|
@ -287,6 +288,46 @@ void Application::initPubsub()
|
||||||
chan->addOrReplaceTimeout(msg);
|
chan->addOrReplaceTimeout(msg);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
this->twitch.pubsub->signals_.moderation.messageDeleted.connect(
|
||||||
|
[&](const auto &action) {
|
||||||
|
auto chan =
|
||||||
|
this->twitch.server->getChannelOrEmptyByID(action.roomID);
|
||||||
|
|
||||||
|
if (chan->isEmpty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageBuilder msg;
|
||||||
|
TwitchMessageBuilder::deletionMessage(action, &msg);
|
||||||
|
msg->flags.set(MessageFlag::PubSub);
|
||||||
|
|
||||||
|
postToThread([chan, msg = msg.release()] {
|
||||||
|
auto replaced = false;
|
||||||
|
LimitedQueueSnapshot<MessagePtr> snapshot =
|
||||||
|
chan->getMessageSnapshot();
|
||||||
|
int snapshotLength = snapshot.size();
|
||||||
|
|
||||||
|
// without parens it doesn't build on windows
|
||||||
|
int end = (std::max)(0, snapshotLength - 200);
|
||||||
|
|
||||||
|
for (int i = snapshotLength - 1; i >= end; --i)
|
||||||
|
{
|
||||||
|
auto &s = snapshot[i];
|
||||||
|
if (!s->flags.has(MessageFlag::PubSub) &&
|
||||||
|
s->timeoutUser == msg->timeoutUser)
|
||||||
|
{
|
||||||
|
chan->replaceMessage(s, msg);
|
||||||
|
replaced = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!replaced)
|
||||||
|
{
|
||||||
|
chan->addMessage(msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
this->twitch.pubsub->signals_.moderation.userUnbanned.connect(
|
this->twitch.pubsub->signals_.moderation.userUnbanned.connect(
|
||||||
[&](const auto &action) {
|
[&](const auto &action) {
|
||||||
|
|
|
@ -75,6 +75,15 @@ struct BanAction : PubSubAction {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct DeleteAction : PubSubAction {
|
||||||
|
using PubSubAction::PubSubAction;
|
||||||
|
|
||||||
|
ActionUser target;
|
||||||
|
|
||||||
|
QString messageId;
|
||||||
|
QString messageText;
|
||||||
|
};
|
||||||
|
|
||||||
struct UnbanAction : PubSubAction {
|
struct UnbanAction : PubSubAction {
|
||||||
using PubSubAction::PubSubAction;
|
using PubSubAction::PubSubAction;
|
||||||
|
|
||||||
|
|
|
@ -428,6 +428,46 @@ PubSub::PubSub()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this->moderationActionHandlers["delete"] = [this](const auto &data,
|
||||||
|
const auto &roomID) {
|
||||||
|
DeleteAction action(data, roomID);
|
||||||
|
|
||||||
|
getCreatedByUser(data, action.source);
|
||||||
|
getTargetUser(data, action.target);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const auto &args = getArgs(data);
|
||||||
|
|
||||||
|
if (args.Size() < 3)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rj::getSafe(args[0], action.target.name))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rj::getSafe(args[1], action.messageText))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rj::getSafe(args[2], action.messageId))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->signals_.moderation.messageDeleted.invoke(action);
|
||||||
|
}
|
||||||
|
catch (const std::runtime_error &ex)
|
||||||
|
{
|
||||||
|
qCDebug(chatterinoPubsub)
|
||||||
|
<< "Error parsing moderation action:" << ex.what();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
this->moderationActionHandlers["ban"] = [this](const auto &data,
|
this->moderationActionHandlers["ban"] = [this](const auto &data,
|
||||||
const auto &roomID) {
|
const auto &roomID) {
|
||||||
BanAction action(data, roomID);
|
BanAction action(data, roomID);
|
||||||
|
|
|
@ -124,6 +124,7 @@ public:
|
||||||
struct {
|
struct {
|
||||||
struct {
|
struct {
|
||||||
Signal<ClearChatAction> chatCleared;
|
Signal<ClearChatAction> chatCleared;
|
||||||
|
Signal<DeleteAction> messageDeleted;
|
||||||
Signal<ModeChangedAction> modeChanged;
|
Signal<ModeChangedAction> modeChanged;
|
||||||
Signal<ModerationStateAction> moderationStateChanged;
|
Signal<ModerationStateAction> moderationStateChanged;
|
||||||
|
|
||||||
|
|
|
@ -1352,6 +1352,8 @@ void TwitchMessageBuilder::hostingSystemMessage(const QString &channelName,
|
||||||
MessageColor::System, FontStyle::ChatMediumBold)
|
MessageColor::System, FontStyle::ChatMediumBold)
|
||||||
->setLink({Link::UserInfo, channelName});
|
->setLink({Link::UserInfo, channelName});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// irc variant
|
||||||
void TwitchMessageBuilder::deletionMessage(const MessagePtr originalMessage,
|
void TwitchMessageBuilder::deletionMessage(const MessagePtr originalMessage,
|
||||||
MessageBuilder *builder)
|
MessageBuilder *builder)
|
||||||
{
|
{
|
||||||
|
@ -1373,7 +1375,7 @@ void TwitchMessageBuilder::deletionMessage(const MessagePtr originalMessage,
|
||||||
if (originalMessage->messageText.length() > 50)
|
if (originalMessage->messageText.length() > 50)
|
||||||
{
|
{
|
||||||
builder->emplace<TextElement>(
|
builder->emplace<TextElement>(
|
||||||
originalMessage->messageText.left(50) + "...",
|
originalMessage->messageText.left(50) + "…",
|
||||||
MessageElementFlag::Text, MessageColor::Text);
|
MessageElementFlag::Text, MessageColor::Text);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1382,6 +1384,44 @@ void TwitchMessageBuilder::deletionMessage(const MessagePtr originalMessage,
|
||||||
MessageElementFlag::Text,
|
MessageElementFlag::Text,
|
||||||
MessageColor::Text);
|
MessageColor::Text);
|
||||||
}
|
}
|
||||||
|
builder->message().timeoutUser = "msg:" + originalMessage->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// pubsub variant
|
||||||
|
void TwitchMessageBuilder::deletionMessage(const DeleteAction &action,
|
||||||
|
MessageBuilder *builder)
|
||||||
|
{
|
||||||
|
builder->emplace<TimestampElement>();
|
||||||
|
builder->message().flags.set(MessageFlag::System);
|
||||||
|
builder->message().flags.set(MessageFlag::DoNotTriggerNotification);
|
||||||
|
builder->message().flags.set(MessageFlag::Timeout);
|
||||||
|
|
||||||
|
builder
|
||||||
|
->emplace<TextElement>(action.source.name, MessageElementFlag::Username,
|
||||||
|
MessageColor::System, FontStyle::ChatMediumBold)
|
||||||
|
->setLink({Link::UserInfo, action.source.name});
|
||||||
|
// TODO(mm2pl): If or when jumping to a single message gets implemented a link,
|
||||||
|
// add a link to the originalMessage
|
||||||
|
builder->emplace<TextElement>(
|
||||||
|
"deleted message from", MessageElementFlag::Text, MessageColor::System);
|
||||||
|
builder
|
||||||
|
->emplace<TextElement>(action.target.name, MessageElementFlag::Username,
|
||||||
|
MessageColor::System, FontStyle::ChatMediumBold)
|
||||||
|
->setLink({Link::UserInfo, action.target.name});
|
||||||
|
builder->emplace<TextElement>("saying:", MessageElementFlag::Text,
|
||||||
|
MessageColor::System);
|
||||||
|
if (action.messageText.length() > 50)
|
||||||
|
{
|
||||||
|
builder->emplace<TextElement>(action.messageText.left(50) + "…",
|
||||||
|
MessageElementFlag::Text,
|
||||||
|
MessageColor::Text);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
builder->emplace<TextElement>(
|
||||||
|
action.messageText, MessageElementFlag::Text, MessageColor::Text);
|
||||||
|
}
|
||||||
|
builder->message().timeoutUser = "msg:" + action.messageId;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace chatterino
|
} // namespace chatterino
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "common/Outcome.hpp"
|
#include "common/Outcome.hpp"
|
||||||
#include "messages/SharedMessageBuilder.hpp"
|
#include "messages/SharedMessageBuilder.hpp"
|
||||||
#include "providers/twitch/ChannelPointReward.hpp"
|
#include "providers/twitch/ChannelPointReward.hpp"
|
||||||
|
#include "providers/twitch/PubsubActions.hpp"
|
||||||
#include "providers/twitch/TwitchBadge.hpp"
|
#include "providers/twitch/TwitchBadge.hpp"
|
||||||
|
|
||||||
#include <IrcMessage>
|
#include <IrcMessage>
|
||||||
|
@ -60,6 +61,8 @@ public:
|
||||||
MessageBuilder *builder);
|
MessageBuilder *builder);
|
||||||
static void deletionMessage(const MessagePtr originalMessage,
|
static void deletionMessage(const MessagePtr originalMessage,
|
||||||
MessageBuilder *builder);
|
MessageBuilder *builder);
|
||||||
|
static void deletionMessage(const DeleteAction &action,
|
||||||
|
MessageBuilder *builder);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void parseUsernameColor() override;
|
void parseUsernameColor() override;
|
||||||
|
|
Loading…
Reference in a new issue