mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
parent
ebe0f0c87f
commit
eae2c2c521
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include "debug/log.hpp"
|
#include "debug/log.hpp"
|
||||||
#include "messages/image.hpp"
|
#include "messages/image.hpp"
|
||||||
|
#include "util/benchmark.hpp"
|
||||||
|
#include "util/rapidjson-helpers.hpp"
|
||||||
#include "util/urlfetch.hpp"
|
#include "util/urlfetch.hpp"
|
||||||
|
|
||||||
#define TWITCH_EMOTE_TEMPLATE "https://static-cdn.jtvnw.net/emoticons/v1/{id}/{scale}"
|
#define TWITCH_EMOTE_TEMPLATE "https://static-cdn.jtvnw.net/emoticons/v1/{id}/{scale}"
|
||||||
|
@ -41,8 +43,58 @@ QString cleanUpCode(const QString &dirtyEmoteCode)
|
||||||
return dirtyEmoteCode;
|
return dirtyEmoteCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void loadSetData(std::shared_ptr<TwitchEmotes::EmoteSet> emoteSet)
|
||||||
|
{
|
||||||
|
debug::Log("Load twitch emote set data for {}", emoteSet->key);
|
||||||
|
util::NetworkRequest req("https://braize.pajlada.com/chatterino/twitchemotes/set/" +
|
||||||
|
emoteSet->key + "/");
|
||||||
|
|
||||||
|
req.setRequestType(util::NetworkRequest::GetRequest);
|
||||||
|
|
||||||
|
req.onError([](int errorCode) -> bool {
|
||||||
|
debug::Log("Emote sets on ERROR {}", errorCode);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
req.onSuccess([emoteSet](const rapidjson::Document &root) -> bool {
|
||||||
|
debug::Log("Emote sets on success");
|
||||||
|
if (!root.IsObject()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string emoteSetID;
|
||||||
|
QString channelName;
|
||||||
|
if (!rj::getSafe(root, "channel_name", channelName)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
emoteSet->channelName = channelName;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
req.execute();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
TwitchEmotes::TwitchEmotes()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
EmoteSet emoteSet;
|
||||||
|
emoteSet.key = "19194";
|
||||||
|
emoteSet.text = "Twitch Prime Emotes";
|
||||||
|
this->staticEmoteSets[emoteSet.key] = std::move(emoteSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
EmoteSet emoteSet;
|
||||||
|
emoteSet.key = "0";
|
||||||
|
emoteSet.text = "Twitch Global Emotes";
|
||||||
|
this->staticEmoteSets[emoteSet.key] = std::move(emoteSet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// id is used for lookup
|
// id is used for lookup
|
||||||
// emoteName is used for giving a name to the emote in case it doesn't exist
|
// emoteName is used for giving a name to the emote in case it doesn't exist
|
||||||
util::EmoteData TwitchEmotes::getEmoteById(const QString &id, const QString &emoteName)
|
util::EmoteData TwitchEmotes::getEmoteById(const QString &id, const QString &emoteName)
|
||||||
|
@ -107,23 +159,26 @@ void TwitchEmotes::refresh(const std::shared_ptr<TwitchAccount> &user)
|
||||||
|
|
||||||
auto emoticonSets = root.value("emoticon_sets").toObject();
|
auto emoticonSets = root.value("emoticon_sets").toObject();
|
||||||
for (QJsonObject::iterator it = emoticonSets.begin(); it != emoticonSets.end(); ++it) {
|
for (QJsonObject::iterator it = emoticonSets.begin(); it != emoticonSets.end(); ++it) {
|
||||||
EmoteSet emoteSet;
|
auto emoteSet = std::make_shared<EmoteSet>();
|
||||||
|
|
||||||
emoteSet.key = it.key();
|
emoteSet->key = it.key();
|
||||||
|
|
||||||
|
loadSetData(emoteSet);
|
||||||
|
|
||||||
for (QJsonValue emoteValue : it.value().toArray()) {
|
for (QJsonValue emoteValue : it.value().toArray()) {
|
||||||
QJsonObject emoticon = emoteValue.toObject();
|
QJsonObject emoticon = emoteValue.toObject();
|
||||||
QString id = QString::number(emoticon["id"].toInt());
|
QString id = QString::number(emoticon["id"].toInt());
|
||||||
QString code = emoticon["code"].toString();
|
QString code = emoticon["code"].toString();
|
||||||
|
|
||||||
auto cleanCode = cleanUpCode(code);
|
auto cleanCode = cleanUpCode(code);
|
||||||
emoteSet.emotes.emplace_back(id, cleanCode);
|
emoteSet->emotes.emplace_back(id, cleanCode);
|
||||||
emoteData.emoteCodes.push_back(cleanCode);
|
emoteData.emoteCodes.push_back(cleanCode);
|
||||||
|
|
||||||
util::EmoteData emote = this->getEmoteById(id, code);
|
util::EmoteData emote = this->getEmoteById(id, code);
|
||||||
emoteData.emotes.insert(code, emote);
|
emoteData.emotes.insert(code, emote);
|
||||||
}
|
}
|
||||||
|
|
||||||
emoteData.emoteSets.emplace_back(std::move(emoteSet));
|
emoteData.emoteSets.emplace_back(emoteSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
emoteData.filled = true;
|
emoteData.filled = true;
|
||||||
|
@ -132,6 +187,64 @@ void TwitchEmotes::refresh(const std::shared_ptr<TwitchAccount> &user)
|
||||||
util::twitch::getAuthorized(url, clientID, oauthToken, QThread::currentThread(), loadEmotes);
|
util::twitch::getAuthorized(url, clientID, oauthToken, QThread::currentThread(), loadEmotes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TwitchEmotes::loadSetData(std::shared_ptr<TwitchEmotes::EmoteSet> emoteSet)
|
||||||
|
{
|
||||||
|
if (!emoteSet) {
|
||||||
|
debug::Log("null emote set sent");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto staticSetIt = this->staticEmoteSets.find(emoteSet->key);
|
||||||
|
if (staticSetIt != this->staticEmoteSets.end()) {
|
||||||
|
const auto &staticSet = staticSetIt->second;
|
||||||
|
emoteSet->channelName = staticSet.channelName;
|
||||||
|
emoteSet->text = staticSet.text;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug::Log("Load twitch emote set data for {}..", emoteSet->key);
|
||||||
|
util::NetworkRequest req("https://braize.pajlada.com/chatterino/twitchemotes/set/" +
|
||||||
|
emoteSet->key + "/");
|
||||||
|
|
||||||
|
req.setRequestType(util::NetworkRequest::GetRequest);
|
||||||
|
|
||||||
|
req.onError([](int errorCode) -> bool {
|
||||||
|
debug::Log("Emote sets on ERROR {}", errorCode);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
req.onSuccess([emoteSet](const rapidjson::Document &root) -> bool {
|
||||||
|
if (!root.IsObject()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string emoteSetID;
|
||||||
|
QString channelName;
|
||||||
|
QString type;
|
||||||
|
if (!rj::getSafe(root, "channel_name", channelName)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rj::getSafe(root, "type", type)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug::Log("Loaded twitch emote set data for {}!", emoteSet->key);
|
||||||
|
|
||||||
|
if (type == "sub") {
|
||||||
|
emoteSet->text = QString("Twitch Subscriber Emote (%1)").arg(channelName);
|
||||||
|
} else {
|
||||||
|
emoteSet->text = QString("Twitch Account Emote (%1)").arg(channelName);
|
||||||
|
}
|
||||||
|
|
||||||
|
emoteSet->channelName = channelName;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
req.execute();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace twitch
|
} // namespace twitch
|
||||||
} // namespace providers
|
} // namespace providers
|
||||||
} // namespace chatterino
|
} // namespace chatterino
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
namespace providers {
|
namespace providers {
|
||||||
namespace twitch {
|
namespace twitch {
|
||||||
|
@ -15,6 +17,8 @@ namespace twitch {
|
||||||
class TwitchEmotes
|
class TwitchEmotes
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
TwitchEmotes();
|
||||||
|
|
||||||
util::EmoteData getEmoteById(const QString &id, const QString &emoteName);
|
util::EmoteData getEmoteById(const QString &id, const QString &emoteName);
|
||||||
|
|
||||||
/// Twitch emotes
|
/// Twitch emotes
|
||||||
|
@ -36,11 +40,15 @@ public:
|
||||||
|
|
||||||
struct EmoteSet {
|
struct EmoteSet {
|
||||||
QString key;
|
QString key;
|
||||||
|
QString channelName;
|
||||||
|
QString text;
|
||||||
std::vector<TwitchEmote> emotes;
|
std::vector<TwitchEmote> emotes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::map<QString, EmoteSet> staticEmoteSets;
|
||||||
|
|
||||||
struct TwitchAccountEmoteData {
|
struct TwitchAccountEmoteData {
|
||||||
std::vector<EmoteSet> emoteSets;
|
std::vector<std::shared_ptr<EmoteSet>> emoteSets;
|
||||||
|
|
||||||
std::vector<QString> emoteCodes;
|
std::vector<QString> emoteCodes;
|
||||||
|
|
||||||
|
@ -53,6 +61,8 @@ public:
|
||||||
std::map<QString, TwitchAccountEmoteData> emotes;
|
std::map<QString, TwitchAccountEmoteData> emotes;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void loadSetData(std::shared_ptr<TwitchEmotes::EmoteSet> emoteSet);
|
||||||
|
|
||||||
// emote code
|
// emote code
|
||||||
util::ConcurrentMap<QString, providers::twitch::EmoteValue *> _twitchEmotes;
|
util::ConcurrentMap<QString, providers::twitch::EmoteValue *> _twitchEmotes;
|
||||||
|
|
||||||
|
|
|
@ -253,9 +253,9 @@ public:
|
||||||
data.onReplyCreated(reply);
|
data.onReplyCreated(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
QObject::connect(reply, &QNetworkReply::finished, worker, [
|
QObject::connect(reply, &QNetworkReply::finished, worker,
|
||||||
data = std::move(data), worker, reply, onFinished = std::move(onFinished)
|
[data = std::move(data), worker, reply,
|
||||||
]() mutable {
|
onFinished = std::move(onFinished)]() mutable {
|
||||||
if (data.caller == nullptr) {
|
if (data.caller == nullptr) {
|
||||||
QByteArray bytes = reply->readAll();
|
QByteArray bytes = reply->readAll();
|
||||||
data.writeToCache(bytes);
|
data.writeToCache(bytes);
|
||||||
|
@ -303,22 +303,19 @@ public:
|
||||||
{
|
{
|
||||||
switch (this->data.requestType) {
|
switch (this->data.requestType) {
|
||||||
case GetRequest: {
|
case GetRequest: {
|
||||||
debug::Log("Call GET request!");
|
|
||||||
this->executeGet();
|
this->executeGet();
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case PutRequest: {
|
case PutRequest: {
|
||||||
debug::Log("Call PUT request!");
|
|
||||||
this->executePut();
|
this->executePut();
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case DeleteRequest: {
|
case DeleteRequest: {
|
||||||
debug::Log("Call DELETE request!");
|
|
||||||
this->executeDelete();
|
this->executeDelete();
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
debug::Log("Unhandled request type {}", (int)this->data.requestType);
|
debug::Log("[Execute] Unhandled request type {}", (int)this->data.requestType);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -370,8 +367,8 @@ private:
|
||||||
worker->moveToThread(&NetworkManager::workerThread);
|
worker->moveToThread(&NetworkManager::workerThread);
|
||||||
|
|
||||||
if (this->data.caller != nullptr) {
|
if (this->data.caller != nullptr) {
|
||||||
QObject::connect(worker, &NetworkWorker::doneUrl,
|
QObject::connect(worker, &NetworkWorker::doneUrl, this->data.caller,
|
||||||
this->data.caller, [data = this->data](auto reply) mutable {
|
[data = this->data](auto reply) mutable {
|
||||||
if (reply->error() != QNetworkReply::NetworkError::NoError) {
|
if (reply->error() != QNetworkReply::NetworkError::NoError) {
|
||||||
if (data.onError) {
|
if (data.onError) {
|
||||||
data.onError(reply->error());
|
data.onError(reply->error());
|
||||||
|
|
|
@ -92,7 +92,18 @@ void EmotePopup::loadChannel(ChannelPtr _channel)
|
||||||
// TITLE
|
// TITLE
|
||||||
messages::MessageBuilder builder1;
|
messages::MessageBuilder builder1;
|
||||||
|
|
||||||
builder1.append(new TextElement("Twitch Account Emotes", MessageElement::Text));
|
QString setText;
|
||||||
|
if (set->text.isEmpty()) {
|
||||||
|
if (set->channelName.isEmpty()) {
|
||||||
|
setText = "Twitch Account Emotes";
|
||||||
|
} else {
|
||||||
|
setText = "Twitch Account Emotes (" + set->channelName + ")";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setText = set->text;
|
||||||
|
}
|
||||||
|
|
||||||
|
builder1.append(new TextElement(setText, MessageElement::Text));
|
||||||
|
|
||||||
builder1.getMessage()->flags |= Message::Centered;
|
builder1.getMessage()->flags |= Message::Centered;
|
||||||
emoteChannel->addMessage(builder1.getMessage());
|
emoteChannel->addMessage(builder1.getMessage());
|
||||||
|
@ -102,7 +113,7 @@ void EmotePopup::loadChannel(ChannelPtr _channel)
|
||||||
builder2.getMessage()->flags |= Message::Centered;
|
builder2.getMessage()->flags |= Message::Centered;
|
||||||
builder2.getMessage()->flags |= Message::DisableCompactEmotes;
|
builder2.getMessage()->flags |= Message::DisableCompactEmotes;
|
||||||
|
|
||||||
for (const auto &emote : set.emotes) {
|
for (const auto &emote : set->emotes) {
|
||||||
[&](const QString &key, const util::EmoteData &value) {
|
[&](const QString &key, const util::EmoteData &value) {
|
||||||
builder2.append((new EmoteElement(value, MessageElement::Flags::AlwaysShow))
|
builder2.append((new EmoteElement(value, MessageElement::Flags::AlwaysShow))
|
||||||
->setLink(Link(Link::InsertText, key)));
|
->setLink(Link(Link::InsertText, key)));
|
||||||
|
|
Loading…
Reference in a new issue