Files
chatterino2/src/providers/recentmessages/Impl.cpp
2024-11-02 12:54:31 +00:00

117 lines
3.4 KiB
C++

#include "providers/recentmessages/Impl.hpp"
#include "common/Env.hpp"
#include "messages/MessageBuilder.hpp"
#include "providers/twitch/IrcMessageHandler.hpp"
#include "providers/twitch/TwitchChannel.hpp"
#include "util/Helpers.hpp"
#include "util/VectorMessageSink.hpp"
#include <QJsonArray>
#include <QUrlQuery>
namespace chatterino::recentmessages::detail {
// Parse the IRC messages returned in JSON form into Communi messages
std::vector<Communi::IrcMessage *> parseRecentMessages(
const QJsonObject &jsonRoot)
{
const auto jsonMessages = jsonRoot.value("messages").toArray();
std::vector<Communi::IrcMessage *> messages;
if (jsonMessages.empty())
{
return messages;
}
for (const auto &jsonMessage : jsonMessages)
{
auto content = unescapeZeroWidthJoiner(jsonMessage.toString());
auto *message =
Communi::IrcMessage::fromData(content.toUtf8(), nullptr);
messages.emplace_back(message);
}
return messages;
}
// Build Communi messages retrieved from the recent messages API into
// proper chatterino messages.
std::vector<MessagePtr> buildRecentMessages(
std::vector<Communi::IrcMessage *> &messages, Channel *channel)
{
VectorMessageSink sink({}, MessageFlag::RecentMessage);
auto *twitchChannel = dynamic_cast<TwitchChannel *>(channel);
if (!twitchChannel)
{
return {};
}
for (auto *message : messages)
{
if (message->tags().contains("rm-received-ts"))
{
const auto msgDate =
QDateTime::fromMSecsSinceEpoch(
message->tags().value("rm-received-ts").toLongLong())
.date();
// Check if we need to insert a message stating that a new day began
if (msgDate != channel->lastDate_)
{
channel->lastDate_ = msgDate;
auto msg = makeSystemMessage(
QLocale().toString(msgDate, QLocale::LongFormat),
QTime(0, 0));
sink.addMessage(msg, MessageContext::Original);
}
}
IrcMessageHandler::parseMessageInto(message, sink, twitchChannel);
message->deleteLater();
}
return std::move(sink).takeMessages();
}
// Returns the URL to be used for querying the Recent Messages API for the
// given channel.
QUrl constructRecentMessagesUrl(
const QString &name, const int limit,
const std::optional<std::chrono::time_point<std::chrono::system_clock>>
after,
const std::optional<std::chrono::time_point<std::chrono::system_clock>>
before)
{
QUrl url(Env::get().recentMessagesApiUrl.arg(name));
QUrlQuery urlQuery(url);
if (!urlQuery.hasQueryItem("limit"))
{
urlQuery.addQueryItem("limit", QString::number(limit));
}
if (after.has_value())
{
urlQuery.addQueryItem(
"after", QString::number(
std::chrono::duration_cast<std::chrono::milliseconds>(
after->time_since_epoch())
.count()));
}
if (before.has_value())
{
urlQuery.addQueryItem(
"before", QString::number(
std::chrono::duration_cast<std::chrono::milliseconds>(
before->time_since_epoch())
.count()));
}
url.setQuery(urlQuery);
return url;
}
} // namespace chatterino::recentmessages::detail