Split list of emote sets into bunches when performing Ivr API reqeusts (#2856)

This commit is contained in:
Paweł 2021-06-06 19:27:45 +02:00 committed by GitHub
parent f1e843a672
commit 2f568b88ae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 64 additions and 41 deletions

View file

@ -15,6 +15,7 @@
- Minor: Switch to Twitch v2 emote API for animated emote support. (#2863)
- Bugfix: Fixed FFZ emote links for global emotes (#2807, #2808)
- Bugfix: Fix reconnecting when IRC write connection is lost (#1831, #2356, #2850)
- Bugfix: Fixed bit emotes not loading in some rare cases. (#2856)
## 2.3.2

View file

@ -74,8 +74,7 @@ public:
ResultCallback<IvrSubage> resultCallback,
IvrFailureCallback failureCallback);
// https://api.ivr.fi/docs#tag/Twitch/paths/~1twitch~1emoteset~1{setid}/get
// however, we use undocumented endpoint, which takes ?set_id=1,2,3,4,... as query parameter
// https://api.ivr.fi/docs#tag/Twitch/paths/~1twitch~1emoteset/get
void getBulkEmoteSets(QString emoteSetList,
ResultCallback<QJsonArray> successCallback,
IvrFailureCallback failureCallback);

View file

@ -281,11 +281,13 @@ void TwitchAccount::loadUserstateEmotes(QStringList emoteSetKeys)
auto userEmoteSets = emoteData->emoteSets;
QStringList newEmoteSetKeys, currentEmoteSetKeys;
// get list of already fetched emote sets
for (const auto &userEmoteSet : userEmoteSets)
{
currentEmoteSetKeys.push_back(userEmoteSet->key);
}
// filter out emote sets from userstate message, which are not in fetched emote set list
for (const auto &emoteSetKey : emoteSetKeys)
{
@ -301,54 +303,75 @@ void TwitchAccount::loadUserstateEmotes(QStringList emoteSetKeys)
return;
}
getIvr()->getBulkEmoteSets(
newEmoteSetKeys.join(","),
[this](QJsonArray emoteSetArray) {
auto emoteData = this->emotes_.access();
for (auto emoteSet : emoteSetArray)
{
auto newUserEmoteSet = std::make_shared<EmoteSet>();
// splitting newEmoteSetKeys to batches of 100, because Ivr API endpoint accepts a maximum of 100 emotesets at once
constexpr int batchSize = 100;
IvrEmoteSet ivrEmoteSet(emoteSet.toObject());
std::vector<QStringList> batches;
newUserEmoteSet->key = ivrEmoteSet.setId;
batches.reserve((newEmoteSetKeys.size() + 1) / batchSize);
auto name = ivrEmoteSet.login;
name.detach();
name[0] = name[0].toUpper();
for (int i = 0; i < newEmoteSetKeys.size(); i += batchSize)
{
QStringList batch;
for (int j = batchSize * i; j < batchSize; j++)
{
batch.push_back(newEmoteSetKeys.at(j));
}
batches.emplace_back(batch);
}
newUserEmoteSet->text = name;
newUserEmoteSet->type = QString();
newUserEmoteSet->channelName = ivrEmoteSet.login;
for (const auto &emote : ivrEmoteSet.emotes)
for (const auto &batch : batches)
{
getIvr()->getBulkEmoteSets(
batch.join(","),
[this](QJsonArray emoteSetArray) {
auto emoteData = this->emotes_.access();
for (auto emoteSet : emoteSetArray)
{
IvrEmote ivrEmote(emote.toObject());
auto newUserEmoteSet = std::make_shared<EmoteSet>();
auto id = EmoteId{ivrEmote.id};
auto code = EmoteName{ivrEmote.code};
auto cleanCode =
EmoteName{TwitchEmotes::cleanUpEmoteCode(code)};
newUserEmoteSet->emotes.emplace_back(
TwitchEmote{id, cleanCode});
IvrEmoteSet ivrEmoteSet(emoteSet.toObject());
emoteData->allEmoteNames.push_back(cleanCode);
newUserEmoteSet->key = ivrEmoteSet.setId;
auto twitchEmote =
getApp()->emotes->twitch.getOrCreateEmote(id, code);
emoteData->emotes.emplace(code, twitchEmote);
auto name = ivrEmoteSet.login;
name.detach();
name[0] = name[0].toUpper();
newUserEmoteSet->text = name;
newUserEmoteSet->type = QString();
newUserEmoteSet->channelName = ivrEmoteSet.login;
for (const auto &emote : ivrEmoteSet.emotes)
{
IvrEmote ivrEmote(emote.toObject());
auto id = EmoteId{ivrEmote.id};
auto code = EmoteName{ivrEmote.code};
auto cleanCode =
EmoteName{TwitchEmotes::cleanUpEmoteCode(code)};
newUserEmoteSet->emotes.push_back(
TwitchEmote{id, cleanCode});
emoteData->allEmoteNames.push_back(cleanCode);
auto twitchEmote =
getApp()->emotes->twitch.getOrCreateEmote(id, code);
emoteData->emotes.emplace(code, twitchEmote);
}
std::sort(newUserEmoteSet->emotes.begin(),
newUserEmoteSet->emotes.end(),
[](const TwitchEmote &l, const TwitchEmote &r) {
return l.name.string < r.name.string;
});
emoteData->emoteSets.emplace_back(newUserEmoteSet);
}
std::sort(newUserEmoteSet->emotes.begin(),
newUserEmoteSet->emotes.end(),
[](const TwitchEmote &l, const TwitchEmote &r) {
return l.name.string < r.name.string;
});
emoteData->emoteSets.emplace_back(newUserEmoteSet);
}
},
[] {
// fetching emotes failed, ivr API might be down
});
},
[] {
// fetching emotes failed, ivr API might be down
});
};
return;
}
SharedAccessGuard<const TwitchAccount::TwitchAccountEmoteData>