mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
Add a local backup of the Twitch Badges API (#4463)
This commit is contained in:
parent
1ad93b7acc
commit
130b23edaf
|
@ -1,5 +1,5 @@
|
||||||
# emoji.json should remain minified
|
# JSON resources should not be prettified
|
||||||
resources/emoji.json
|
resources/*.json
|
||||||
|
|
||||||
# Ignore submodule files
|
# Ignore submodule files
|
||||||
lib/*/
|
lib/*/
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
## Unversioned
|
## Unversioned
|
||||||
|
|
||||||
- Minor: Added support for FrankerFaceZ animated emotes. (#4434)
|
- Minor: Added support for FrankerFaceZ animated emotes. (#4434)
|
||||||
|
- Minor: Added a local backup of the Twitch Badges API in case the request fails. (#4463)
|
||||||
- Bugfix: Fixed an issue where animated emotes would render on top of zero-width emotes. (#4314)
|
- Bugfix: Fixed an issue where animated emotes would render on top of zero-width emotes. (#4314)
|
||||||
- Bugfix: Fixed an issue where it was difficult to hover a zero-width emote. (#4314)
|
- Bugfix: Fixed an issue where it was difficult to hover a zero-width emote. (#4314)
|
||||||
- Bugfix: Fixed an issue where context-menu items for zero-width emotes displayed the wrong provider. (#4460)
|
- Bugfix: Fixed an issue where context-menu items for zero-width emotes displayed the wrong provider. (#4460)
|
||||||
|
|
1
resources/twitch-badges.json
Normal file
1
resources/twitch-badges.json
Normal file
File diff suppressed because one or more lines are too long
|
@ -9,10 +9,11 @@
|
||||||
#include "util/DisplayBadge.hpp"
|
#include "util/DisplayBadge.hpp"
|
||||||
|
|
||||||
#include <QBuffer>
|
#include <QBuffer>
|
||||||
|
#include <QFile>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <QImageReader>
|
#include <QImageReader>
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
#include <QJsonObject>
|
#include <QJsonDocument>
|
||||||
#include <QJsonValue>
|
#include <QJsonValue>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QUrlQuery>
|
#include <QUrlQuery>
|
||||||
|
@ -36,58 +37,71 @@ void TwitchBadges::loadTwitchBadges()
|
||||||
|
|
||||||
NetworkRequest(url)
|
NetworkRequest(url)
|
||||||
.onSuccess([this](auto result) -> Outcome {
|
.onSuccess([this](auto result) -> Outcome {
|
||||||
{
|
auto root = result.parseJson();
|
||||||
auto root = result.parseJson();
|
|
||||||
auto badgeSets = this->badgeSets_.access();
|
|
||||||
|
|
||||||
auto jsonSets = root.value("badge_sets").toObject();
|
this->parseTwitchBadges(root);
|
||||||
for (auto sIt = jsonSets.begin(); sIt != jsonSets.end(); ++sIt)
|
|
||||||
{
|
|
||||||
auto key = sIt.key();
|
|
||||||
auto versions =
|
|
||||||
sIt.value().toObject().value("versions").toObject();
|
|
||||||
|
|
||||||
for (auto vIt = versions.begin(); vIt != versions.end();
|
|
||||||
++vIt)
|
|
||||||
{
|
|
||||||
auto versionObj = vIt.value().toObject();
|
|
||||||
|
|
||||||
auto emote = Emote{
|
|
||||||
{""},
|
|
||||||
ImageSet{
|
|
||||||
Image::fromUrl({versionObj.value("image_url_1x")
|
|
||||||
.toString()},
|
|
||||||
1),
|
|
||||||
Image::fromUrl({versionObj.value("image_url_2x")
|
|
||||||
.toString()},
|
|
||||||
.5),
|
|
||||||
Image::fromUrl({versionObj.value("image_url_4x")
|
|
||||||
.toString()},
|
|
||||||
.25),
|
|
||||||
},
|
|
||||||
Tooltip{versionObj.value("title").toString()},
|
|
||||||
Url{versionObj.value("click_url").toString()}};
|
|
||||||
// "title"
|
|
||||||
// "clickAction"
|
|
||||||
|
|
||||||
(*badgeSets)[key][vIt.key()] =
|
|
||||||
std::make_shared<Emote>(emote);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this->loaded();
|
this->loaded();
|
||||||
return Success;
|
return Success;
|
||||||
})
|
})
|
||||||
.onError([this](auto res) {
|
.onError([this](auto res) {
|
||||||
qCDebug(chatterinoTwitch)
|
qCWarning(chatterinoTwitch)
|
||||||
<< "Error loading Twitch Badges:" << res.status();
|
<< "Error loading Twitch Badges from the badges API:"
|
||||||
// Despite erroring out, we still want to reach the same point
|
<< res.status() << " - falling back to backup";
|
||||||
// Loaded should still be set to true to not build up an endless queue, and the quuee should still be flushed.
|
QFile file(":/twitch-badges.json");
|
||||||
|
if (!file.open(QFile::ReadOnly))
|
||||||
|
{
|
||||||
|
// Despite erroring out, we still want to reach the same point
|
||||||
|
// Loaded should still be set to true to not build up an endless queue, and the quuee should still be flushed.
|
||||||
|
qCWarning(chatterinoTwitch)
|
||||||
|
<< "Error loading Twitch Badges from the local backup file";
|
||||||
|
this->loaded();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto bytes = file.readAll();
|
||||||
|
auto doc = QJsonDocument::fromJson(bytes);
|
||||||
|
|
||||||
|
this->parseTwitchBadges(doc.object());
|
||||||
|
|
||||||
this->loaded();
|
this->loaded();
|
||||||
})
|
})
|
||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TwitchBadges::parseTwitchBadges(QJsonObject root)
|
||||||
|
{
|
||||||
|
auto badgeSets = this->badgeSets_.access();
|
||||||
|
|
||||||
|
auto jsonSets = root.value("badge_sets").toObject();
|
||||||
|
for (auto sIt = jsonSets.begin(); sIt != jsonSets.end(); ++sIt)
|
||||||
|
{
|
||||||
|
auto key = sIt.key();
|
||||||
|
auto versions = sIt.value().toObject().value("versions").toObject();
|
||||||
|
|
||||||
|
for (auto vIt = versions.begin(); vIt != versions.end(); ++vIt)
|
||||||
|
{
|
||||||
|
auto versionObj = vIt.value().toObject();
|
||||||
|
|
||||||
|
auto emote = Emote{
|
||||||
|
{""},
|
||||||
|
ImageSet{
|
||||||
|
Image::fromUrl(
|
||||||
|
{versionObj.value("image_url_1x").toString()}, 1),
|
||||||
|
Image::fromUrl(
|
||||||
|
{versionObj.value("image_url_2x").toString()}, .5),
|
||||||
|
Image::fromUrl(
|
||||||
|
{versionObj.value("image_url_4x").toString()}, .25),
|
||||||
|
},
|
||||||
|
Tooltip{versionObj.value("title").toString()},
|
||||||
|
Url{versionObj.value("click_url").toString()}};
|
||||||
|
// "title"
|
||||||
|
// "clickAction"
|
||||||
|
|
||||||
|
(*badgeSets)[key][vIt.key()] = std::make_shared<Emote>(emote);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TwitchBadges::loaded()
|
void TwitchBadges::loaded()
|
||||||
{
|
{
|
||||||
std::unique_lock loadedLock(this->loadedMutex_);
|
std::unique_lock loadedLock(this->loadedMutex_);
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
#include <pajlada/signals/signal.hpp>
|
#include <pajlada/signals/signal.hpp>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
|
#include <QJsonObject>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
|
@ -49,6 +50,10 @@ private:
|
||||||
|
|
||||||
TwitchBadges();
|
TwitchBadges();
|
||||||
void loadTwitchBadges();
|
void loadTwitchBadges();
|
||||||
|
/**
|
||||||
|
* @brief Accepts a JSON blob from https://badges.twitch.tv/v1/badges/global/display and updates our badges with it
|
||||||
|
**/
|
||||||
|
void parseTwitchBadges(QJsonObject root);
|
||||||
void loaded();
|
void loaded();
|
||||||
void loadEmoteImage(const QString &name, ImagePtr image,
|
void loadEmoteImage(const QString &name, ImagePtr image,
|
||||||
BadgeIconCallback &&callback);
|
BadgeIconCallback &&callback);
|
||||||
|
|
Loading…
Reference in a new issue