mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-21 22:24:07 +01:00
Switch to v2 of RAnders00's recent-messages API, so we support showing
old sub messages and stuff
This commit is contained in:
parent
a4cba22bcb
commit
8b3867fa7d
4 changed files with 183 additions and 39 deletions
|
@ -44,6 +44,46 @@ IrcMessageHandler &IrcMessageHandler::getInstance()
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<MessagePtr> IrcMessageHandler::parseMessage(
|
||||||
|
Channel *channel, Communi::IrcMessage *message)
|
||||||
|
{
|
||||||
|
std::vector<MessagePtr> builtMessages;
|
||||||
|
|
||||||
|
auto command = message->command();
|
||||||
|
|
||||||
|
if (command == "PRIVMSG")
|
||||||
|
{
|
||||||
|
return this->parsePrivMessage(
|
||||||
|
channel, static_cast<Communi::IrcPrivateMessage *>(message));
|
||||||
|
}
|
||||||
|
else if (command == "USERNOTICE")
|
||||||
|
{
|
||||||
|
return this->parseUserNoticeMessage(channel, message);
|
||||||
|
}
|
||||||
|
else if (command == "NOTICE")
|
||||||
|
{
|
||||||
|
return this->parseNoticeMessage(
|
||||||
|
static_cast<Communi::IrcNoticeMessage *>(message));
|
||||||
|
}
|
||||||
|
|
||||||
|
return builtMessages;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<MessagePtr> IrcMessageHandler::parsePrivMessage(
|
||||||
|
Channel *channel, Communi::IrcPrivateMessage *message)
|
||||||
|
{
|
||||||
|
log("Parse priv msg");
|
||||||
|
std::vector<MessagePtr> builtMessages;
|
||||||
|
MessageParseArgs args;
|
||||||
|
TwitchMessageBuilder builder(channel, message, args, message->content(),
|
||||||
|
message->isAction());
|
||||||
|
if (!builder.isIgnored())
|
||||||
|
{
|
||||||
|
builtMessages.emplace_back(builder.build());
|
||||||
|
}
|
||||||
|
return builtMessages;
|
||||||
|
}
|
||||||
|
|
||||||
void IrcMessageHandler::handlePrivMessage(Communi::IrcPrivateMessage *message,
|
void IrcMessageHandler::handlePrivMessage(Communi::IrcPrivateMessage *message,
|
||||||
TwitchServer &server)
|
TwitchServer &server)
|
||||||
{
|
{
|
||||||
|
@ -302,6 +342,56 @@ void IrcMessageHandler::handleWhisperMessage(Communi::IrcMessage *message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<MessagePtr> IrcMessageHandler::parseUserNoticeMessage(
|
||||||
|
Channel *channel, Communi::IrcMessage *message)
|
||||||
|
{
|
||||||
|
std::vector<MessagePtr> builtMessages;
|
||||||
|
|
||||||
|
auto data = message->toData();
|
||||||
|
|
||||||
|
auto tags = message->tags();
|
||||||
|
auto parameters = message->parameters();
|
||||||
|
|
||||||
|
auto target = parameters[0];
|
||||||
|
QString msgType = tags.value("msg-id", "").toString();
|
||||||
|
QString content;
|
||||||
|
if (parameters.size() >= 2)
|
||||||
|
{
|
||||||
|
content = parameters[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msgType == "sub" || msgType == "resub" || msgType == "subgift")
|
||||||
|
{
|
||||||
|
// Sub-specific message. I think it's only allowed for "resub" messages
|
||||||
|
// atm
|
||||||
|
if (!content.isEmpty())
|
||||||
|
{
|
||||||
|
MessageParseArgs args;
|
||||||
|
args.trimSubscriberUsername = true;
|
||||||
|
|
||||||
|
TwitchMessageBuilder builder(channel, message, args, content,
|
||||||
|
false);
|
||||||
|
builder->flags.set(MessageFlag::Subscription);
|
||||||
|
builder->flags.unset(MessageFlag::Highlighted);
|
||||||
|
builtMessages.emplace_back(builder.build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = tags.find("system-msg");
|
||||||
|
|
||||||
|
if (it != tags.end())
|
||||||
|
{
|
||||||
|
auto b = MessageBuilder(systemMessage,
|
||||||
|
parseTagString(it.value().toString()));
|
||||||
|
|
||||||
|
b->flags.set(MessageFlag::Subscription);
|
||||||
|
auto newMessage = b.release();
|
||||||
|
builtMessages.emplace_back(newMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
return builtMessages;
|
||||||
|
}
|
||||||
|
|
||||||
void IrcMessageHandler::handleUserNoticeMessage(Communi::IrcMessage *message,
|
void IrcMessageHandler::handleUserNoticeMessage(Communi::IrcMessage *message,
|
||||||
TwitchServer &server)
|
TwitchServer &server)
|
||||||
{
|
{
|
||||||
|
@ -381,11 +471,23 @@ void IrcMessageHandler::handleModeMessage(Communi::IrcMessage *message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<MessagePtr> IrcMessageHandler::parseNoticeMessage(
|
||||||
|
Communi::IrcNoticeMessage *message)
|
||||||
|
{
|
||||||
|
std::vector<MessagePtr> builtMessages;
|
||||||
|
|
||||||
|
builtMessages.emplace_back(makeSystemMessage(message->content()));
|
||||||
|
|
||||||
|
return builtMessages;
|
||||||
|
}
|
||||||
|
|
||||||
void IrcMessageHandler::handleNoticeMessage(Communi::IrcNoticeMessage *message)
|
void IrcMessageHandler::handleNoticeMessage(Communi::IrcNoticeMessage *message)
|
||||||
{
|
{
|
||||||
auto app = getApp();
|
auto app = getApp();
|
||||||
MessagePtr msg = makeSystemMessage(message->content());
|
auto builtMessages = this->parseNoticeMessage(message);
|
||||||
|
|
||||||
|
for (auto msg : builtMessages)
|
||||||
|
{
|
||||||
QString channelName;
|
QString channelName;
|
||||||
if (!trimChannelName(message->target(), channelName))
|
if (!trimChannelName(message->target(), channelName))
|
||||||
{
|
{
|
||||||
|
@ -403,7 +505,8 @@ void IrcMessageHandler::handleNoticeMessage(Communi::IrcNoticeMessage *message)
|
||||||
|
|
||||||
if (channel->isEmpty())
|
if (channel->isEmpty())
|
||||||
{
|
{
|
||||||
log("[IrcManager:handleNoticeMessage] Channel {} not found in channel "
|
log("[IrcManager:handleNoticeMessage] Channel {} not found in "
|
||||||
|
"channel "
|
||||||
"manager ",
|
"manager ",
|
||||||
channelName);
|
channelName);
|
||||||
return;
|
return;
|
||||||
|
@ -411,6 +514,7 @@ void IrcMessageHandler::handleNoticeMessage(Communi::IrcNoticeMessage *message)
|
||||||
|
|
||||||
channel->addMessage(msg);
|
channel->addMessage(msg);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void IrcMessageHandler::handleWriteConnectionNoticeMessage(
|
void IrcMessageHandler::handleWriteConnectionNoticeMessage(
|
||||||
Communi::IrcNoticeMessage *message)
|
Communi::IrcNoticeMessage *message)
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <IrcMessage>
|
#include <IrcMessage>
|
||||||
|
#include "messages/Message.hpp"
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
|
||||||
class TwitchServer;
|
class TwitchServer;
|
||||||
|
class Channel;
|
||||||
|
|
||||||
class IrcMessageHandler
|
class IrcMessageHandler
|
||||||
{
|
{
|
||||||
|
@ -13,6 +15,13 @@ class IrcMessageHandler
|
||||||
public:
|
public:
|
||||||
static IrcMessageHandler &getInstance();
|
static IrcMessageHandler &getInstance();
|
||||||
|
|
||||||
|
// parseMessage parses a single IRC message into 0+ Chatterino messages
|
||||||
|
std::vector<MessagePtr> parseMessage(Channel *channel,
|
||||||
|
Communi::IrcMessage *message);
|
||||||
|
|
||||||
|
// parsePrivMessage arses a single IRC PRIVMSG into 0-1 Chatterino messages
|
||||||
|
std::vector<MessagePtr> parsePrivMessage(
|
||||||
|
Channel *channel, Communi::IrcPrivateMessage *message);
|
||||||
void handlePrivMessage(Communi::IrcPrivateMessage *message,
|
void handlePrivMessage(Communi::IrcPrivateMessage *message,
|
||||||
TwitchServer &server);
|
TwitchServer &server);
|
||||||
|
|
||||||
|
@ -20,10 +29,22 @@ public:
|
||||||
void handleClearChatMessage(Communi::IrcMessage *message);
|
void handleClearChatMessage(Communi::IrcMessage *message);
|
||||||
void handleUserStateMessage(Communi::IrcMessage *message);
|
void handleUserStateMessage(Communi::IrcMessage *message);
|
||||||
void handleWhisperMessage(Communi::IrcMessage *message);
|
void handleWhisperMessage(Communi::IrcMessage *message);
|
||||||
|
|
||||||
|
// parseUserNoticeMessage parses a single IRC USERNOTICE message into 0+
|
||||||
|
// chatterino messages
|
||||||
|
std::vector<MessagePtr> parseUserNoticeMessage(
|
||||||
|
Channel *channel, Communi::IrcMessage *message);
|
||||||
void handleUserNoticeMessage(Communi::IrcMessage *message,
|
void handleUserNoticeMessage(Communi::IrcMessage *message,
|
||||||
TwitchServer &server);
|
TwitchServer &server);
|
||||||
|
|
||||||
void handleModeMessage(Communi::IrcMessage *message);
|
void handleModeMessage(Communi::IrcMessage *message);
|
||||||
|
|
||||||
|
// parseNoticeMessage parses a single IRC NOTICE message into 0+ chatterino
|
||||||
|
// messages
|
||||||
|
std::vector<MessagePtr> parseNoticeMessage(
|
||||||
|
Communi::IrcNoticeMessage *message);
|
||||||
void handleNoticeMessage(Communi::IrcNoticeMessage *message);
|
void handleNoticeMessage(Communi::IrcNoticeMessage *message);
|
||||||
|
|
||||||
void handleWriteConnectionNoticeMessage(Communi::IrcNoticeMessage *message);
|
void handleWriteConnectionNoticeMessage(Communi::IrcNoticeMessage *message);
|
||||||
|
|
||||||
void handleJoinMessage(Communi::IrcMessage *message);
|
void handleJoinMessage(Communi::IrcMessage *message);
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "messages/Message.hpp"
|
#include "messages/Message.hpp"
|
||||||
#include "providers/bttv/BttvEmotes.hpp"
|
#include "providers/bttv/BttvEmotes.hpp"
|
||||||
#include "providers/bttv/LoadBttvChannelEmote.hpp"
|
#include "providers/bttv/LoadBttvChannelEmote.hpp"
|
||||||
|
#include "providers/twitch/IrcMessageHandler.hpp"
|
||||||
#include "providers/twitch/PubsubClient.hpp"
|
#include "providers/twitch/PubsubClient.hpp"
|
||||||
#include "providers/twitch/TwitchCommon.hpp"
|
#include "providers/twitch/TwitchCommon.hpp"
|
||||||
#include "providers/twitch/TwitchMessageBuilder.hpp"
|
#include "providers/twitch/TwitchMessageBuilder.hpp"
|
||||||
|
@ -29,10 +30,12 @@
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
namespace {
|
namespace {
|
||||||
|
// parseRecentMessages takes a json object and returns a vector of
|
||||||
|
// Communi IrcMessages
|
||||||
auto parseRecentMessages(const QJsonObject &jsonRoot, ChannelPtr channel)
|
auto parseRecentMessages(const QJsonObject &jsonRoot, ChannelPtr channel)
|
||||||
{
|
{
|
||||||
QJsonArray jsonMessages = jsonRoot.value("messages").toArray();
|
QJsonArray jsonMessages = jsonRoot.value("messages").toArray();
|
||||||
std::vector<MessagePtr> messages;
|
std::vector<Communi::IrcMessage *> messages;
|
||||||
|
|
||||||
if (jsonMessages.empty())
|
if (jsonMessages.empty())
|
||||||
return messages;
|
return messages;
|
||||||
|
@ -40,18 +43,8 @@ namespace {
|
||||||
for (const auto jsonMessage : jsonMessages)
|
for (const auto jsonMessage : jsonMessages)
|
||||||
{
|
{
|
||||||
auto content = jsonMessage.toString().toUtf8();
|
auto content = jsonMessage.toString().toUtf8();
|
||||||
// passing nullptr as the channel makes the message invalid but we
|
messages.emplace_back(
|
||||||
// don't check for that anyways
|
Communi::IrcMessage::fromData(content, nullptr));
|
||||||
auto message = Communi::IrcMessage::fromData(content, nullptr);
|
|
||||||
auto privMsg = dynamic_cast<Communi::IrcPrivateMessage *>(message);
|
|
||||||
assert(privMsg);
|
|
||||||
|
|
||||||
MessageParseArgs args;
|
|
||||||
TwitchMessageBuilder builder(channel.get(), privMsg, args);
|
|
||||||
builder.message().flags.set(MessageFlag::RecentMessage);
|
|
||||||
|
|
||||||
if (!builder.isIgnored())
|
|
||||||
messages.push_back(builder.build());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return messages;
|
return messages;
|
||||||
|
@ -611,8 +604,8 @@ Outcome TwitchChannel::parseLiveStatus(const rapidjson::Document &document)
|
||||||
|
|
||||||
void TwitchChannel::loadRecentMessages()
|
void TwitchChannel::loadRecentMessages()
|
||||||
{
|
{
|
||||||
static QString genericURL =
|
static QString genericURL = "https://recent-messages.robotty.de/api/v2/"
|
||||||
"https://recent-messages.robotty.de/v1/recent-messages/%1";
|
"recent-messages/%1?clearchatToNotice=true";
|
||||||
|
|
||||||
NetworkRequest request(genericURL.arg(this->getName()));
|
NetworkRequest request(genericURL.arg(this->getName()));
|
||||||
request.setCaller(QThread::currentThread());
|
request.setCaller(QThread::currentThread());
|
||||||
|
@ -626,7 +619,21 @@ void TwitchChannel::loadRecentMessages()
|
||||||
|
|
||||||
auto messages = parseRecentMessages(result.parseJson(), shared);
|
auto messages = parseRecentMessages(result.parseJson(), shared);
|
||||||
|
|
||||||
shared->addMessagesAtStart(messages);
|
auto &handler = IrcMessageHandler::getInstance();
|
||||||
|
|
||||||
|
std::vector<MessagePtr> allBuiltMessages;
|
||||||
|
|
||||||
|
for (auto message : messages)
|
||||||
|
{
|
||||||
|
for (auto builtMessage :
|
||||||
|
handler.parseMessage(shared.get(), message))
|
||||||
|
{
|
||||||
|
builtMessage->flags.set(MessageFlag::RecentMessage);
|
||||||
|
allBuiltMessages.emplace_back(builtMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shared->addMessagesAtStart(allBuiltMessages);
|
||||||
|
|
||||||
return Success;
|
return Success;
|
||||||
});
|
});
|
||||||
|
|
|
@ -109,12 +109,24 @@ MessagePtr TwitchMessageBuilder::build()
|
||||||
|
|
||||||
this->appendChannelName();
|
this->appendChannelName();
|
||||||
|
|
||||||
|
if (this->tags.contains("rm-deleted"))
|
||||||
|
{
|
||||||
|
this->message().flags.set(MessageFlag::Disabled);
|
||||||
|
}
|
||||||
|
|
||||||
// timestamp
|
// timestamp
|
||||||
bool isPastMsg = this->tags.contains("historical");
|
bool isPastMsg = this->tags.contains("historical");
|
||||||
if (isPastMsg)
|
if (isPastMsg)
|
||||||
{
|
{
|
||||||
// This may be architecture dependent(datatype)
|
// This may be architecture dependent(datatype)
|
||||||
qint64 ts = this->tags.value("tmi-sent-ts").toLongLong();
|
bool customReceived = false;
|
||||||
|
qint64 ts =
|
||||||
|
this->tags.value("rm-received-ts").toLongLong(&customReceived);
|
||||||
|
if (!customReceived)
|
||||||
|
{
|
||||||
|
ts = this->tags.value("tmi-sent-ts").toLongLong();
|
||||||
|
}
|
||||||
|
|
||||||
QDateTime dateTime = QDateTime::fromMSecsSinceEpoch(ts);
|
QDateTime dateTime = QDateTime::fromMSecsSinceEpoch(ts);
|
||||||
this->emplace<TimestampElement>(dateTime.time());
|
this->emplace<TimestampElement>(dateTime.time());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue