Add support FrankerFaceZ badges. (#2101)
On startup, we poll https://api.frankerfacez.com/v1/badges/ids and store the mappings of user IDs to badges for the remainder of the applications lifetime.
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
#include "FfzBadges.hpp"
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonValue>
|
||||
#include <QThread>
|
||||
#include "common/NetworkRequest.hpp"
|
||||
#include "common/Outcome.hpp"
|
||||
#include "messages/Emote.hpp"
|
||||
|
||||
#include <QUrl>
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
void FfzBadges::initialize(Settings &settings, Paths &paths)
|
||||
{
|
||||
this->loadFfzBadges();
|
||||
}
|
||||
|
||||
boost::optional<EmotePtr> FfzBadges::getBadge(const UserId &id)
|
||||
{
|
||||
auto it = this->badgeMap.find(id.string);
|
||||
if (it != this->badgeMap.end())
|
||||
{
|
||||
return this->badges[it->second];
|
||||
}
|
||||
return boost::none;
|
||||
}
|
||||
boost::optional<QColor> FfzBadges::getBadgeColor(const UserId &id)
|
||||
{
|
||||
auto badgeIt = this->badgeMap.find(id.string);
|
||||
if (badgeIt != this->badgeMap.end())
|
||||
{
|
||||
auto colorIt = this->colorMap.find(badgeIt->second);
|
||||
if (colorIt != this->colorMap.end())
|
||||
{
|
||||
return colorIt->second;
|
||||
}
|
||||
return boost::none;
|
||||
}
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
void FfzBadges::loadFfzBadges()
|
||||
{
|
||||
static QUrl url("https://api.frankerfacez.com/v1/badges/ids");
|
||||
|
||||
NetworkRequest(url)
|
||||
.onSuccess([this](auto result) -> Outcome {
|
||||
auto jsonRoot = result.parseJson();
|
||||
int index = 0;
|
||||
for (const auto &jsonBadge_ : jsonRoot.value("badges").toArray())
|
||||
{
|
||||
auto jsonBadge = jsonBadge_.toObject();
|
||||
auto jsonUrls = jsonBadge.value("urls").toObject();
|
||||
|
||||
auto emote = Emote{
|
||||
EmoteName{},
|
||||
ImageSet{
|
||||
Url{QString("https:") + jsonUrls.value("1").toString()},
|
||||
Url{QString("https:") + jsonUrls.value("2").toString()},
|
||||
Url{QString("https:") +
|
||||
jsonUrls.value("4").toString()}},
|
||||
Tooltip{jsonBadge.value("title").toString()}, Url{}};
|
||||
|
||||
this->badges.push_back(
|
||||
std::make_shared<const Emote>(std::move(emote)));
|
||||
this->colorMap[index] =
|
||||
QColor(jsonBadge.value("color").toString());
|
||||
|
||||
auto badgeId = QString::number(jsonBadge.value("id").toInt());
|
||||
for (const auto &user : jsonRoot.value("users")
|
||||
.toObject()
|
||||
.value(badgeId)
|
||||
.toArray())
|
||||
{
|
||||
this->badgeMap[QString::number(user.toInt())] = index;
|
||||
}
|
||||
++index;
|
||||
}
|
||||
|
||||
return Success;
|
||||
})
|
||||
.execute();
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
#include <common/Singleton.hpp>
|
||||
|
||||
#include "common/Aliases.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
struct Emote;
|
||||
using EmotePtr = std::shared_ptr<const Emote>;
|
||||
|
||||
class FfzBadges : public Singleton
|
||||
{
|
||||
public:
|
||||
virtual void initialize(Settings &settings, Paths &paths) override;
|
||||
FfzBadges() = default;
|
||||
|
||||
boost::optional<EmotePtr> getBadge(const UserId &id);
|
||||
boost::optional<QColor> getBadgeColor(const UserId &id);
|
||||
|
||||
private:
|
||||
void loadFfzBadges();
|
||||
std::map<QString, int> badgeMap;
|
||||
std::vector<EmotePtr> badges;
|
||||
std::map<int, QColor> colorMap;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "controllers/ignores/IgnorePhrase.hpp"
|
||||
#include "messages/Message.hpp"
|
||||
#include "providers/chatterino/ChatterinoBadges.hpp"
|
||||
#include "providers/ffz/FfzBadges.hpp"
|
||||
#include "providers/twitch/TwitchBadges.hpp"
|
||||
#include "providers/twitch/TwitchChannel.hpp"
|
||||
#include "providers/twitch/TwitchCommon.hpp"
|
||||
@@ -255,6 +256,7 @@ MessagePtr TwitchMessageBuilder::build()
|
||||
this->appendTwitchBadges();
|
||||
|
||||
this->appendChatterinoBadges();
|
||||
this->appendFfzBadges();
|
||||
|
||||
this->appendUsername();
|
||||
|
||||
@@ -1090,6 +1092,18 @@ void TwitchMessageBuilder::appendChatterinoBadges()
|
||||
}
|
||||
}
|
||||
|
||||
void TwitchMessageBuilder::appendFfzBadges()
|
||||
{
|
||||
if (auto badge = getApp()->ffzBadges->getBadge({this->userId_}))
|
||||
{
|
||||
if (auto color = getApp()->ffzBadges->getBadgeColor({this->userId_}))
|
||||
{
|
||||
this->emplace<FfzBadgeElement>(*badge, MessageElementFlag::BadgeFfz,
|
||||
color.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Outcome TwitchMessageBuilder::tryParseCheermote(const QString &string)
|
||||
{
|
||||
if (this->bitsLeft == 0)
|
||||
|
||||
@@ -75,6 +75,7 @@ private:
|
||||
|
||||
void appendTwitchBadges();
|
||||
void appendChatterinoBadges();
|
||||
void appendFfzBadges();
|
||||
Outcome tryParseCheermote(const QString &string);
|
||||
|
||||
QString roomID_;
|
||||
|
||||
Reference in New Issue
Block a user