From 9abe7883b75615bc0471ba411e77c0366b255964 Mon Sep 17 00:00:00 2001 From: ZonianMidian <57513632+ZonianMidian@users.noreply.github.com> Date: Tue, 11 Apr 2023 14:21:32 -0500 Subject: [PATCH 01/31] Initial implementation of Helix.cpp & Helix.hpp --- src/providers/twitch/api/Helix.cpp | 108 +++++++++++++++++++++++++++++ src/providers/twitch/api/Helix.hpp | 12 ++++ 2 files changed, 120 insertions(+) diff --git a/src/providers/twitch/api/Helix.cpp b/src/providers/twitch/api/Helix.cpp index 5df03372e09..66bfad3fce9 100644 --- a/src/providers/twitch/api/Helix.cpp +++ b/src/providers/twitch/api/Helix.cpp @@ -2468,6 +2468,114 @@ void Helix::startCommercial( .execute(); } +// Twitch global badges +// https://dev.twitch.tv/docs/api/reference/#get-global-chat-badges +void Helix::getGlobalBadges( + ResultCallback successCallback, + FailureCallback failureCallback) +{ + using Error = HelixGetGlobalBadgesError; + this->makeRequest("chat/badges/global") + .onSuccess([successCallback](auto result) -> Outcome { + if (result.status() != 200) + { + qCWarning(chatterinoTwitch) + << "Success result for getting global badges was " + << result.status() << "but we expected it to be 200"; + } + + auto response = result.parseJson(); + successCallback(HelixGlobalBadges(response)); + return Success; + }) + .onError([failureCallback](auto result) { + auto obj = result.parseJson(); + auto message = obj.value("message").toString(); + + switch (result.status()) + { + case 401: { + if (message.contains("OAuth token")) + { + failureCallback(Error::UserNotAuthorized, message); + } + else + { + failureCallback(Error::Forwarded, message); + } + } + break; + + default: { + qCDebug(chatterinoTwitch) + << "Unhandled error data:" << result.status() + << result.getData() << obj; + failureCallback(Error::Unknown, message); + } + break; + } + }) + .execute(); +} + +// Badges for the `broadcasterID` channel +// https://dev.twitch.tv/docs/api/reference/#get-channel-chat-badges +void Helix::getChannelBadges( + QString broadcasterID, ResultCallback successCallback, + FailureCallback failureCallback) +{ + using Error = HelixGetChannelBadgesError; + QUrlQuery urlQuery; + urlQuery.addQueryItem("broadcaster_id", broadcasterID); + + this->makeRequest("chat/badges", urlQuery) + .onSuccess([successCallback](auto result) -> Outcome { + if (result.status() != 200) + { + qCWarning(chatterinoTwitch) + << "Success result for getting badges was " + << result.status() << "but we expected it to be 200"; + } + + auto response = result.parseJson(); + successCallback(HelixChannelBadges(response)); + return Success; + }) + .onError([failureCallback](auto result) { + auto obj = result.parseJson(); + auto message = obj.value("message").toString(); + + switch (result.status()) + { + case 400: { + failureCallback(Error::Forwarded, message); + } + break; + + case 401: { + if (message.contains("OAuth token")) + { + failureCallback(Error::UserNotAuthorized, message); + } + else + { + failureCallback(Error::Forwarded, message); + } + } + break; + + default: { + qCDebug(chatterinoTwitch) + << "Unhandled error data:" << result.status() + << result.getData() << obj; + failureCallback(Error::Unknown, message); + } + break; + } + }) + .execute(); +} + NetworkRequest Helix::makeRequest(QString url, QUrlQuery urlQuery) { assert(!url.startsWith("/")); diff --git a/src/providers/twitch/api/Helix.hpp b/src/providers/twitch/api/Helix.hpp index 42242fc8e06..ebfc08a203b 100644 --- a/src/providers/twitch/api/Helix.hpp +++ b/src/providers/twitch/api/Helix.hpp @@ -1184,6 +1184,18 @@ class Helix final : public IHelix FailureCallback failureCallback) final; + // Get global Twitch badges + // https://dev.twitch.tv/docs/api/reference/#get-global-chat-badges + void getGlobalBadges( + ResultCallback successCallback, + FailureCallback failureCallback) final; + + // Get badges for the `broadcasterID` channel + // https://dev.twitch.tv/docs/api/reference/#get-channel-chat-badges + void getChannelBadges( + QString broadcasterID, ResultCallback successCallback, + FailureCallback failureCallback) final; + void update(QString clientId, QString oauthToken) final; static void initialize(); From ad945915e0d2acc751fe2c6997bb24cd67045971 Mon Sep 17 00:00:00 2001 From: ZonianMidian <57513632+ZonianMidian@users.noreply.github.com> Date: Tue, 11 Apr 2023 14:29:02 -0500 Subject: [PATCH 02/31] Add changelog item --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 535af230591..f51898ad6f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - Minor: Added the ability to reply to a message by `Shift + Right Click`ing the username. (#4424) - Minor: Added better filter validation and error messages. (#4364) - Minor: Updated the look of the Black Theme to be more in line with the other themes. (#4523) +- Minor: Migrated badges to Helix API. (#4537) - 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 context-menu items for zero-width emotes displayed the wrong provider. (#4460) From e538c4af549324014a44f698db53d6db58f1b228 Mon Sep 17 00:00:00 2001 From: ZonianMidian <57513632+ZonianMidian@users.noreply.github.com> Date: Tue, 11 Apr 2023 15:22:35 -0500 Subject: [PATCH 03/31] Class declaration for errors --- src/providers/twitch/api/Helix.hpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/providers/twitch/api/Helix.hpp b/src/providers/twitch/api/Helix.hpp index ebfc08a203b..25713179d9c 100644 --- a/src/providers/twitch/api/Helix.hpp +++ b/src/providers/twitch/api/Helix.hpp @@ -616,6 +616,22 @@ enum class HelixStartCommercialError { Forwarded, }; +enum class HelixGetGlobalBadgesError { + Unknown, + UserNotAuthorized, + + // The error message is forwarded directly from the Twitch API + Forwarded, +}; + +enum class HelixGetChannelBadgesError { + Unknown, + UserNotAuthorized, + + // The error message is forwarded directly from the Twitch API + Forwarded, +}; + class IHelix { public: From b997784ea8f15a9bd0e166a4c8f8580fdf372d23 Mon Sep 17 00:00:00 2001 From: ZonianMidian <57513632+ZonianMidian@users.noreply.github.com> Date: Wed, 12 Apr 2023 02:57:16 -0500 Subject: [PATCH 04/31] New implementations and fixes for Helix.cpp and Helix.hpp --- src/providers/twitch/api/Helix.cpp | 30 +++++----------- src/providers/twitch/api/Helix.hpp | 58 +++++++++++++++++++++++++++--- 2 files changed, 62 insertions(+), 26 deletions(-) diff --git a/src/providers/twitch/api/Helix.cpp b/src/providers/twitch/api/Helix.cpp index 66bfad3fce9..15881325335 100644 --- a/src/providers/twitch/api/Helix.cpp +++ b/src/providers/twitch/api/Helix.cpp @@ -2476,6 +2476,8 @@ void Helix::getGlobalBadges( { using Error = HelixGetGlobalBadgesError; this->makeRequest("chat/badges/global") + .type(NetworkRequestType::Get) + .header("Content-Type", "application/json") .onSuccess([successCallback](auto result) -> Outcome { if (result.status() != 200) { @@ -2495,14 +2497,7 @@ void Helix::getGlobalBadges( switch (result.status()) { case 401: { - if (message.contains("OAuth token")) - { - failureCallback(Error::UserNotAuthorized, message); - } - else - { - failureCallback(Error::Forwarded, message); - } + failureCallback(Error::Forwarded, message); } break; @@ -2529,6 +2524,8 @@ void Helix::getChannelBadges( urlQuery.addQueryItem("broadcaster_id", broadcasterID); this->makeRequest("chat/badges", urlQuery) + .type(NetworkRequestType::Get) + .header("Content-Type", "application/json") .onSuccess([successCallback](auto result) -> Outcome { if (result.status() != 200) { @@ -2546,21 +2543,10 @@ void Helix::getChannelBadges( auto message = obj.value("message").toString(); switch (result.status()) - { - case 400: { - failureCallback(Error::Forwarded, message); - } - break; - + { + case 400: case 401: { - if (message.contains("OAuth token")) - { - failureCallback(Error::UserNotAuthorized, message); - } - else - { - failureCallback(Error::Forwarded, message); - } + failureCallback(Error::Forwarded, message); } break; diff --git a/src/providers/twitch/api/Helix.hpp b/src/providers/twitch/api/Helix.hpp index 25713179d9c..690911cba97 100644 --- a/src/providers/twitch/api/Helix.hpp +++ b/src/providers/twitch/api/Helix.hpp @@ -384,6 +384,59 @@ struct HelixModerators { } }; +struct HelixBadgeVersion +{ + QString id; + Url imageURL1x; + Url imageURL2x; + Url imageURL4x; + QString title; + QString clickURL; + + explicit HelixBadgeVersion(QJsonObject jsonObject) + : id(jsonObject.value("id").toString()) + , imageURL1x(Url{jsonObject.value("image_url_1x").toString()}) + , imageURL2x(Url{jsonObject.value("image_url_2x").toString()}) + , imageURL4x(Url{jsonObject.value("image_url_4x").toString()}) + , title(jsonObject.value("title").toString()) + , clickURL(Url{jsonObject.value("click_url").toString()}) + { + } +}; + +struct HelixBadgeSet +{ + QString set_id; + std::vector versions; + + explicit HelixBadgeSet(const QJsonObject& json) + : set_id(json.value("set_id").toString()) + { + const auto json_versions = json.value("versions").toArray(); + for (const auto& version : json_versions) + { + HelixBadgeVersion badge_version(version.toObject()); + versions.push_back(badge_version); + } + } +}; + +struct HelixGlobalBadges { + std::vector data; + HelixGlobalBadges() = default; + explicit HelixGlobalBadges(const QJsonObject &jsonObject) + { + const auto &data = jsonObject.value("data").toArray(); + for (const auto &set : data) + { + HelixBadgeSet badgeSet(set.toObject()); + this->data.push_back(badgeSet); + } + } +}; + +using HelixChannelBadges = HelixGlobalBadges; + enum class HelixAnnouncementColor { Blue, Green, @@ -618,7 +671,6 @@ enum class HelixStartCommercialError { enum class HelixGetGlobalBadgesError { Unknown, - UserNotAuthorized, // The error message is forwarded directly from the Twitch API Forwarded, @@ -626,7 +678,6 @@ enum class HelixGetGlobalBadgesError { enum class HelixGetChannelBadgesError { Unknown, - UserNotAuthorized, // The error message is forwarded directly from the Twitch API Forwarded, @@ -912,8 +963,7 @@ class IHelix virtual void startCommercial( QString broadcasterID, int length, ResultCallback successCallback, - FailureCallback - failureCallback) = 0; + FailureCallback failureCallback) = 0; virtual void update(QString clientId, QString oauthToken) = 0; From cdaf33cc1eb0e9657426f19ed3b8456ff9c3bb1d Mon Sep 17 00:00:00 2001 From: ZonianMidian <57513632+ZonianMidian@users.noreply.github.com> Date: Wed, 12 Apr 2023 03:00:26 -0500 Subject: [PATCH 05/31] Minor correction --- src/providers/twitch/api/Helix.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/providers/twitch/api/Helix.hpp b/src/providers/twitch/api/Helix.hpp index 690911cba97..ae702392f8e 100644 --- a/src/providers/twitch/api/Helix.hpp +++ b/src/providers/twitch/api/Helix.hpp @@ -406,11 +406,11 @@ struct HelixBadgeVersion struct HelixBadgeSet { - QString set_id; + QString setID; std::vector versions; explicit HelixBadgeSet(const QJsonObject& json) - : set_id(json.value("set_id").toString()) + : setID(json.value("set_id").toString()) { const auto json_versions = json.value("versions").toArray(); for (const auto& version : json_versions) From e0db1e4effa7acf0743e37da3ffbac47ba5c3b5d Mon Sep 17 00:00:00 2001 From: Zonian <57513632+ZonianMidian@users.noreply.github.com> Date: Wed, 12 Apr 2023 03:18:13 -0500 Subject: [PATCH 06/31] Class correction for clickURL in Helix.hpp Co-authored-by: iProdigy <8106344+iProdigy@users.noreply.github.com> --- src/providers/twitch/api/Helix.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/providers/twitch/api/Helix.hpp b/src/providers/twitch/api/Helix.hpp index ae702392f8e..df8773c9e36 100644 --- a/src/providers/twitch/api/Helix.hpp +++ b/src/providers/twitch/api/Helix.hpp @@ -391,7 +391,7 @@ struct HelixBadgeVersion Url imageURL2x; Url imageURL4x; QString title; - QString clickURL; + Url clickURL; explicit HelixBadgeVersion(QJsonObject jsonObject) : id(jsonObject.value("id").toString()) From ae4e27ad25713d92ea6819fe90d117ce62c38471 Mon Sep 17 00:00:00 2001 From: ZonianMidian <57513632+ZonianMidian@users.noreply.github.com> Date: Wed, 12 Apr 2023 14:00:42 -0500 Subject: [PATCH 07/31] Removed unnecessary Content-Type --- src/providers/twitch/api/Helix.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/providers/twitch/api/Helix.cpp b/src/providers/twitch/api/Helix.cpp index 15881325335..20ec957168e 100644 --- a/src/providers/twitch/api/Helix.cpp +++ b/src/providers/twitch/api/Helix.cpp @@ -2477,7 +2477,6 @@ void Helix::getGlobalBadges( using Error = HelixGetGlobalBadgesError; this->makeRequest("chat/badges/global") .type(NetworkRequestType::Get) - .header("Content-Type", "application/json") .onSuccess([successCallback](auto result) -> Outcome { if (result.status() != 200) { @@ -2525,7 +2524,6 @@ void Helix::getChannelBadges( this->makeRequest("chat/badges", urlQuery) .type(NetworkRequestType::Get) - .header("Content-Type", "application/json") .onSuccess([successCallback](auto result) -> Outcome { if (result.status() != 200) { From cd0c55d08d2bafc5c23872d3bf9364404c4d9b05 Mon Sep 17 00:00:00 2001 From: ZonianMidian <57513632+ZonianMidian@users.noreply.github.com> Date: Wed, 12 Apr 2023 14:17:07 -0500 Subject: [PATCH 08/31] Virtual functions getGlobalBadges and getChannelBadges defined in IHelix --- src/providers/twitch/api/Helix.hpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/providers/twitch/api/Helix.hpp b/src/providers/twitch/api/Helix.hpp index df8773c9e36..386e77ebda2 100644 --- a/src/providers/twitch/api/Helix.hpp +++ b/src/providers/twitch/api/Helix.hpp @@ -965,6 +965,18 @@ class IHelix ResultCallback successCallback, FailureCallback failureCallback) = 0; + // Get global Twitch badges + // https://dev.twitch.tv/docs/api/reference/#get-global-chat-badges + virtual void getGlobalBadges( + ResultCallback successCallback, + FailureCallback failureCallback) = 0; + + // Get badges for the `broadcasterID` channel + // https://dev.twitch.tv/docs/api/reference/#get-channel-chat-badges + virtual void getChannelBadges( + QString broadcasterID, ResultCallback successCallback, + FailureCallback failureCallback) = 0; + virtual void update(QString clientId, QString oauthToken) = 0; protected: From ca8653da8310db41c8107c0aaaa3ad1fa2c12a2c Mon Sep 17 00:00:00 2001 From: ZonianMidian <57513632+ZonianMidian@users.noreply.github.com> Date: Wed, 12 Apr 2023 14:39:06 -0500 Subject: [PATCH 09/31] Added missing --- src/providers/twitch/api/Helix.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/providers/twitch/api/Helix.cpp b/src/providers/twitch/api/Helix.cpp index 20ec957168e..35c2912458b 100644 --- a/src/providers/twitch/api/Helix.cpp +++ b/src/providers/twitch/api/Helix.cpp @@ -2475,7 +2475,7 @@ void Helix::getGlobalBadges( FailureCallback failureCallback) { using Error = HelixGetGlobalBadgesError; - this->makeRequest("chat/badges/global") + this->makeRequest("chat/badges/global", QUrlQuery()) .type(NetworkRequestType::Get) .onSuccess([successCallback](auto result) -> Outcome { if (result.status() != 200) From 8702f8af81d41136aa59586f4221c52c29182c48 Mon Sep 17 00:00:00 2001 From: ZonianMidian <57513632+ZonianMidian@users.noreply.github.com> Date: Thu, 13 Apr 2023 02:34:24 -0500 Subject: [PATCH 10/31] Added mock method to MockHelix for HelixGlobalBadges and HelixChannelBadges --- tests/src/HighlightController.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/src/HighlightController.cpp b/tests/src/HighlightController.cpp index a3f37b26b1a..02fa1045b14 100644 --- a/tests/src/HighlightController.cpp +++ b/tests/src/HighlightController.cpp @@ -224,6 +224,17 @@ class MockHelix : public IHelix ResultCallback> successCallback, HelixFailureCallback failureCallback), (override)); + + MOCK_METHOD(void, getGlobalBadges, + (ResultCallback successCallback, + FailureCallback failureCallback), + (override)); + + MOCK_METHOD(void, getChannelBadges, + (QString broadcasterID, + ResultCallback successCallback, + FailureCallback failureCallback), + (override)); // The extra parenthesis around the failure callback is because its type contains a comma MOCK_METHOD(void, updateUserChatColor, From 88cb0707817670085c086ad9ff363cdf6d66ad22 Mon Sep 17 00:00:00 2001 From: Zonian <57513632+ZonianMidian@users.noreply.github.com> Date: Thu, 13 Apr 2023 04:19:16 -0500 Subject: [PATCH 11/31] Added extra parenthesis in mock method Co-authored-by: iProdigy <8106344+iProdigy@users.noreply.github.com> --- tests/src/HighlightController.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/src/HighlightController.cpp b/tests/src/HighlightController.cpp index 02fa1045b14..143a8ca244b 100644 --- a/tests/src/HighlightController.cpp +++ b/tests/src/HighlightController.cpp @@ -225,15 +225,17 @@ class MockHelix : public IHelix HelixFailureCallback failureCallback), (override)); + // The extra parenthesis around the failure callback is because its type contains a comma MOCK_METHOD(void, getGlobalBadges, (ResultCallback successCallback, - FailureCallback failureCallback), + (FailureCallback failureCallback)), (override)); + // The extra parenthesis around the failure callback is because its type contains a comma MOCK_METHOD(void, getChannelBadges, (QString broadcasterID, ResultCallback successCallback, - FailureCallback failureCallback), + (FailureCallback failureCallback)), (override)); // The extra parenthesis around the failure callback is because its type contains a comma From a0841cb8886a5748051ce105c71141767fef9acb Mon Sep 17 00:00:00 2001 From: ZonianMidian <57513632+ZonianMidian@users.noreply.github.com> Date: Fri, 14 Apr 2023 03:47:52 -0500 Subject: [PATCH 12/31] Correction of file formatting --- src/providers/twitch/api/Helix.cpp | 2 +- src/providers/twitch/api/Helix.hpp | 35 ++++++++++++++++-------------- tests/src/HighlightController.cpp | 14 +++++++----- 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/src/providers/twitch/api/Helix.cpp b/src/providers/twitch/api/Helix.cpp index 35c2912458b..b73347c2030 100644 --- a/src/providers/twitch/api/Helix.cpp +++ b/src/providers/twitch/api/Helix.cpp @@ -2541,7 +2541,7 @@ void Helix::getChannelBadges( auto message = obj.value("message").toString(); switch (result.status()) - { + { case 400: case 401: { failureCallback(Error::Forwarded, message); diff --git a/src/providers/twitch/api/Helix.hpp b/src/providers/twitch/api/Helix.hpp index 386e77ebda2..510b07357e8 100644 --- a/src/providers/twitch/api/Helix.hpp +++ b/src/providers/twitch/api/Helix.hpp @@ -384,8 +384,7 @@ struct HelixModerators { } }; -struct HelixBadgeVersion -{ +struct HelixBadgeVersion { QString id; Url imageURL1x; Url imageURL2x; @@ -404,16 +403,15 @@ struct HelixBadgeVersion } }; -struct HelixBadgeSet -{ +struct HelixBadgeSet { QString setID; std::vector versions; - explicit HelixBadgeSet(const QJsonObject& json) + explicit HelixBadgeSet(const QJsonObject &json) : setID(json.value("set_id").toString()) { const auto json_versions = json.value("versions").toArray(); - for (const auto& version : json_versions) + for (const auto &version : json_versions) { HelixBadgeVersion badge_version(version.toObject()); versions.push_back(badge_version); @@ -963,19 +961,23 @@ class IHelix virtual void startCommercial( QString broadcasterID, int length, ResultCallback successCallback, - FailureCallback failureCallback) = 0; + FailureCallback + failureCallback) = 0; // Get global Twitch badges // https://dev.twitch.tv/docs/api/reference/#get-global-chat-badges virtual void getGlobalBadges( ResultCallback successCallback, - FailureCallback failureCallback) = 0; + FailureCallback + failureCallback) = 0; // Get badges for the `broadcasterID` channel // https://dev.twitch.tv/docs/api/reference/#get-channel-chat-badges virtual void getChannelBadges( - QString broadcasterID, ResultCallback successCallback, - FailureCallback failureCallback) = 0; + QString broadcasterID, + ResultCallback successCallback, + FailureCallback + failureCallback) = 0; virtual void update(QString clientId, QString oauthToken) = 0; @@ -1264,15 +1266,16 @@ class Helix final : public IHelix // Get global Twitch badges // https://dev.twitch.tv/docs/api/reference/#get-global-chat-badges - void getGlobalBadges( - ResultCallback successCallback, - FailureCallback failureCallback) final; + void getGlobalBadges(ResultCallback successCallback, + FailureCallback + failureCallback) final; // Get badges for the `broadcasterID` channel // https://dev.twitch.tv/docs/api/reference/#get-channel-chat-badges - void getChannelBadges( - QString broadcasterID, ResultCallback successCallback, - FailureCallback failureCallback) final; + void getChannelBadges(QString broadcasterID, + ResultCallback successCallback, + FailureCallback + failureCallback) final; void update(QString clientId, QString oauthToken) final; diff --git a/tests/src/HighlightController.cpp b/tests/src/HighlightController.cpp index 143a8ca244b..181ca57a3b8 100644 --- a/tests/src/HighlightController.cpp +++ b/tests/src/HighlightController.cpp @@ -224,18 +224,20 @@ class MockHelix : public IHelix ResultCallback> successCallback, HelixFailureCallback failureCallback), (override)); - + // The extra parenthesis around the failure callback is because its type contains a comma - MOCK_METHOD(void, getGlobalBadges, - (ResultCallback successCallback, - (FailureCallback failureCallback)), - (override)); + MOCK_METHOD( + void, getGlobalBadges, + (ResultCallback successCallback, + (FailureCallback failureCallback)), + (override)); // The extra parenthesis around the failure callback is because its type contains a comma MOCK_METHOD(void, getChannelBadges, (QString broadcasterID, ResultCallback successCallback, - (FailureCallback failureCallback)), + (FailureCallback + failureCallback)), (override)); // The extra parenthesis around the failure callback is because its type contains a comma From 97c4f526d5369897520d31346449d9cf319fa644 Mon Sep 17 00:00:00 2001 From: ZonianMidian <57513632+ZonianMidian@users.noreply.github.com> Date: Sat, 15 Apr 2023 18:22:53 -0500 Subject: [PATCH 13/31] Implementation of getGlobalsBadges in TwitchBadges.cpp --- src/providers/twitch/TwitchBadges.cpp | 45 +++++++++++++++++---------- src/providers/twitch/TwitchBadges.hpp | 3 -- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/src/providers/twitch/TwitchBadges.cpp b/src/providers/twitch/TwitchBadges.cpp index e959f66cba7..fecc1813866 100644 --- a/src/providers/twitch/TwitchBadges.cpp +++ b/src/providers/twitch/TwitchBadges.cpp @@ -6,6 +6,7 @@ #include "common/QLogging.hpp" #include "messages/Emote.hpp" #include "messages/Image.hpp" +#include "providers/twitch/api/Helix.hpp" #include "util/DisplayBadge.hpp" #include @@ -29,25 +30,36 @@ void TwitchBadges::loadTwitchBadges() { assert(this->loaded_ == false); - QUrl url("https://badges.twitch.tv/v1/badges/global/display"); + getHelix()->getGlobalBadges( + [this](auto result) { + auto globalBadges = HelixGlobalBadges{result}; + auto badgeSets = this->badgeSets_.access(); - QUrlQuery urlQuery; - urlQuery.addQueryItem("language", "en"); - url.setQuery(urlQuery); - - NetworkRequest(url) - .onSuccess([this](auto result) -> Outcome { - auto root = result.parseJson(); - - this->parseTwitchBadges(root); + for (const auto &badgeSet : globalBadges.data) + { + const auto &setID = badgeSet.setID; + for (const auto &version : badgeSet.versions) + { + const auto &emote = + Emote{{""}, + ImageSet{ + Image::fromUrl(version.imageURL1x), + Image::fromUrl(version.imageURL2x, .5), + Image::fromUrl(version.imageURL4x, .25), + }, + Tooltip{version.title}, + version.clickURL}; + (*badgeSets)[setID][version.id] = + std::make_shared(emote); + } + } this->loaded(); - return Success; - }) - .onError([this](auto res) { + }, + [this](auto error, auto message) { qCWarning(chatterinoTwitch) - << "Error loading Twitch Badges from the badges API:" - << res.status() << " - falling back to backup"; + << "Error loading Twitch Badges from the Helix API:" + << static_cast(error) << " - falling back to backup"; QFile file(":/twitch-badges.json"); if (!file.open(QFile::ReadOnly)) { @@ -64,8 +76,7 @@ void TwitchBadges::loadTwitchBadges() this->parseTwitchBadges(doc.object()); this->loaded(); - }) - .execute(); + }); } void TwitchBadges::parseTwitchBadges(QJsonObject root) diff --git a/src/providers/twitch/TwitchBadges.hpp b/src/providers/twitch/TwitchBadges.hpp index a87e2246d37..42b2494db52 100644 --- a/src/providers/twitch/TwitchBadges.hpp +++ b/src/providers/twitch/TwitchBadges.hpp @@ -50,9 +50,6 @@ class TwitchBadges TwitchBadges(); 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 loadEmoteImage(const QString &name, ImagePtr image, From 30811e925bd25fb6800d869cc7b72ccb65515fa5 Mon Sep 17 00:00:00 2001 From: ZonianMidian <57513632+ZonianMidian@users.noreply.github.com> Date: Sat, 15 Apr 2023 20:39:43 -0500 Subject: [PATCH 14/31] Fixing error message in TwitchBadges.cpp --- src/providers/twitch/TwitchBadges.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/providers/twitch/TwitchBadges.cpp b/src/providers/twitch/TwitchBadges.cpp index fecc1813866..95d678a9ddd 100644 --- a/src/providers/twitch/TwitchBadges.cpp +++ b/src/providers/twitch/TwitchBadges.cpp @@ -57,9 +57,22 @@ void TwitchBadges::loadTwitchBadges() this->loaded(); }, [this](auto error, auto message) { - qCWarning(chatterinoTwitch) - << "Error loading Twitch Badges from the Helix API:" - << static_cast(error) << " - falling back to backup"; + QString errorMessage("Failed to load global badges - "); + + switch (error) + { + case HelixGetGlobalBadgesError::Forwarded: { + errorMessage += message; + } + break; + + // This would most likely happen if the service is down, or if the JSON payload returned has changed format + case HelixGetGlobalBadgesError::Unknown: { + errorMessage += "An unknown error has occurred."; + } + break; + } + qCWarning(chatterinoTwitch) << errorMessage; QFile file(":/twitch-badges.json"); if (!file.open(QFile::ReadOnly)) { From eb59af8871a15fd1466ae07b3e32cf8af0edca44 Mon Sep 17 00:00:00 2001 From: ZonianMidian <57513632+ZonianMidian@users.noreply.github.com> Date: Sat, 15 Apr 2023 20:41:29 -0500 Subject: [PATCH 15/31] Implementation of getChannelBadges in TwitchChannel.cpp --- src/providers/twitch/TwitchChannel.cpp | 79 ++++++++++++++------------ src/providers/twitch/api/Helix.hpp | 7 +-- 2 files changed, 44 insertions(+), 42 deletions(-) diff --git a/src/providers/twitch/TwitchChannel.cpp b/src/providers/twitch/TwitchChannel.cpp index 96c3217cbff..9ccb1576cb6 100644 --- a/src/providers/twitch/TwitchChannel.cpp +++ b/src/providers/twitch/TwitchChannel.cpp @@ -1282,50 +1282,57 @@ void TwitchChannel::cleanUpReplyThreads() void TwitchChannel::refreshBadges() { - auto url = Url{"https://badges.twitch.tv/v1/badges/channels/" + - this->roomId() + "/display?language=en"}; - NetworkRequest(url.string) - - .onSuccess([this, - weak = weakOf(this)](auto result) -> Outcome { - auto shared = weak.lock(); - if (!shared) - return Failure; + if (this->roomId().isEmpty()) + { + return; + } + getHelix()->getChannelBadges( + this->roomId(), + // successCallback + [this](auto result) { + auto channelBadges = HelixChannelBadges{result}; auto badgeSets = this->badgeSets_.access(); - auto jsonRoot = result.parseJson(); + for (const auto &badgeSet : channelBadges.data) + { + const auto &setID = badgeSet.setID; + for (const auto &version : badgeSet.versions) + { + const auto &emote = + Emote{{""}, + ImageSet{ + Image::fromUrl(version.imageURL1x), + Image::fromUrl(version.imageURL2x, .5), + Image::fromUrl(version.imageURL4x, .25), + }, + Tooltip{version.title}, + version.clickURL}; + (*badgeSets)[setID][version.id] = + std::make_shared(emote); + } + } + }, + // failureCallback + [this](auto error, auto message) { + QString errorMessage("Failed to load channel badges - "); - auto _ = jsonRoot["badge_sets"].toObject(); - for (auto jsonBadgeSet = _.begin(); jsonBadgeSet != _.end(); - jsonBadgeSet++) + switch (error) { - auto &versions = (*badgeSets)[jsonBadgeSet.key()]; + case HelixGetChannelBadgesError::Forwarded: { + errorMessage += message; + } + break; - auto _set = jsonBadgeSet->toObject()["versions"].toObject(); - for (auto jsonVersion_ = _set.begin(); - jsonVersion_ != _set.end(); jsonVersion_++) - { - auto jsonVersion = jsonVersion_->toObject(); - auto emote = std::make_shared(Emote{ - EmoteName{}, - ImageSet{ - Image::fromUrl( - {jsonVersion["image_url_1x"].toString()}, 1), - Image::fromUrl( - {jsonVersion["image_url_2x"].toString()}, .5), - Image::fromUrl( - {jsonVersion["image_url_4x"].toString()}, .25)}, - Tooltip{jsonVersion["description"].toString()}, - Url{jsonVersion["clickURL"].toString()}}); - - versions.emplace(jsonVersion_.key(), emote); - }; + // This would most likely happen if the service is down, or if the JSON payload returned has changed format + case HelixGetChannelBadgesError::Unknown: { + errorMessage += "An unknown error has occurred."; + } + break; } - return Success; - }) - .execute(); + this->addMessage(makeSystemMessage(errorMessage)); + }); } void TwitchChannel::refreshCheerEmotes() diff --git a/src/providers/twitch/api/Helix.hpp b/src/providers/twitch/api/Helix.hpp index 510b07357e8..f3b5cb8d7fb 100644 --- a/src/providers/twitch/api/Helix.hpp +++ b/src/providers/twitch/api/Helix.hpp @@ -674,12 +674,7 @@ enum class HelixGetGlobalBadgesError { Forwarded, }; -enum class HelixGetChannelBadgesError { - Unknown, - - // The error message is forwarded directly from the Twitch API - Forwarded, -}; +using HelixGetChannelBadgesError = HelixGetGlobalBadgesError; class IHelix { From 58b07dd534b364d49075bb0d7fe3285df1506c87 Mon Sep 17 00:00:00 2001 From: ZonianMidian <57513632+ZonianMidian@users.noreply.github.com> Date: Sat, 15 Apr 2023 20:55:22 -0500 Subject: [PATCH 16/31] README update on Helix to add the new endpoints --- src/providers/twitch/api/README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/providers/twitch/api/README.md b/src/providers/twitch/api/README.md index b889761840c..b05be517e33 100644 --- a/src/providers/twitch/api/README.md +++ b/src/providers/twitch/api/README.md @@ -136,6 +136,22 @@ Used in: - `providers/twitch/TwitchChannel.cpp` to resolve a chats available cheer emotes. This helps us parse incoming messages like `pajaCheer1000` +### Get Global Badges + +URL: https://dev.twitch.tv/docs/api/reference/#get-global-chat-badges + +Used in: + +- `providers/twitch/TwitchBadges.cpp` to load global badges + +### Get Channel Badges + +URL: https://dev.twitch.tv/docs/api/reference/#get-channel-chat-badges + +Used in: + +- `providers/twitch/TwitchChannel.cpp` to load channel badges + ### Get Emote Sets URL: https://dev.twitch.tv/docs/api/reference#get-emote-sets From 20feb1cf39d0a595910797a3cebdffc05fb063f5 Mon Sep 17 00:00:00 2001 From: Rasmus Karlsson Date: Sun, 16 Apr 2023 08:57:52 +0200 Subject: [PATCH 17/31] nit: const ref HelixBadgeVersion constructor parameter This prevents the parameter from being copied for each invocation - since we know the lifetime of the object this is not a problem --- src/providers/twitch/api/Helix.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/providers/twitch/api/Helix.hpp b/src/providers/twitch/api/Helix.hpp index f3b5cb8d7fb..6ab9f26fd73 100644 --- a/src/providers/twitch/api/Helix.hpp +++ b/src/providers/twitch/api/Helix.hpp @@ -392,7 +392,7 @@ struct HelixBadgeVersion { QString title; Url clickURL; - explicit HelixBadgeVersion(QJsonObject jsonObject) + explicit HelixBadgeVersion(const QJsonObject &jsonObject) : id(jsonObject.value("id").toString()) , imageURL1x(Url{jsonObject.value("image_url_1x").toString()}) , imageURL2x(Url{jsonObject.value("image_url_2x").toString()}) From 17ca5ea838e94b6db36f10d6c8bb1db1ff1a92c5 Mon Sep 17 00:00:00 2001 From: Rasmus Karlsson Date: Sun, 16 Apr 2023 09:14:40 +0200 Subject: [PATCH 18/31] nit: Rename `json_versions` to `jsonVersions` --- src/providers/twitch/api/Helix.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/providers/twitch/api/Helix.hpp b/src/providers/twitch/api/Helix.hpp index 6ab9f26fd73..8637a130116 100644 --- a/src/providers/twitch/api/Helix.hpp +++ b/src/providers/twitch/api/Helix.hpp @@ -410,8 +410,8 @@ struct HelixBadgeSet { explicit HelixBadgeSet(const QJsonObject &json) : setID(json.value("set_id").toString()) { - const auto json_versions = json.value("versions").toArray(); - for (const auto &version : json_versions) + const auto jsonVersions = json.value("versions").toArray(); + for (const auto &version : jsonVersions) { HelixBadgeVersion badge_version(version.toObject()); versions.push_back(badge_version); From 17ac301c02def6eeacd553357b678fb648a8083c Mon Sep 17 00:00:00 2001 From: Rasmus Karlsson Date: Sun, 16 Apr 2023 09:14:58 +0200 Subject: [PATCH 19/31] nit: rename `badge_version` to `badgeVersion` --- src/providers/twitch/api/Helix.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/providers/twitch/api/Helix.hpp b/src/providers/twitch/api/Helix.hpp index 8637a130116..36351a39a28 100644 --- a/src/providers/twitch/api/Helix.hpp +++ b/src/providers/twitch/api/Helix.hpp @@ -413,8 +413,8 @@ struct HelixBadgeSet { const auto jsonVersions = json.value("versions").toArray(); for (const auto &version : jsonVersions) { - HelixBadgeVersion badge_version(version.toObject()); - versions.push_back(badge_version); + HelixBadgeVersion badgeVersion(version.toObject()); + versions.push_back(badgeVersion); } } }; From f50dae6587888fa279a3834e44b9d6962620ef9d Mon Sep 17 00:00:00 2001 From: Rasmus Karlsson Date: Sun, 16 Apr 2023 09:15:17 +0200 Subject: [PATCH 20/31] nit: use emplace_back to in-place construct badges There's not really a big gain in any particular way, but it makes it, imo, more readable since it's less code --- src/providers/twitch/api/Helix.hpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/providers/twitch/api/Helix.hpp b/src/providers/twitch/api/Helix.hpp index 36351a39a28..66ca5a755d9 100644 --- a/src/providers/twitch/api/Helix.hpp +++ b/src/providers/twitch/api/Helix.hpp @@ -413,8 +413,7 @@ struct HelixBadgeSet { const auto jsonVersions = json.value("versions").toArray(); for (const auto &version : jsonVersions) { - HelixBadgeVersion badgeVersion(version.toObject()); - versions.push_back(badgeVersion); + versions.emplace_back(version.toObject()); } } }; @@ -427,8 +426,7 @@ struct HelixGlobalBadges { const auto &data = jsonObject.value("data").toArray(); for (const auto &set : data) { - HelixBadgeSet badgeSet(set.toObject()); - this->data.push_back(badgeSet); + this->data.emplace_back(set.toObject()); } } }; From 1b4f04f61f81659026c83c3cdce61d07a73428c6 Mon Sep 17 00:00:00 2001 From: Rasmus Karlsson Date: Sun, 16 Apr 2023 09:17:21 +0200 Subject: [PATCH 21/31] nit: Remove HelixGlobalBadges default constructor We don't use the default constructor, so we don't need it defined Bonus: This also adds a newline between the member variables & the constructor --- src/providers/twitch/api/Helix.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/providers/twitch/api/Helix.hpp b/src/providers/twitch/api/Helix.hpp index 66ca5a755d9..80cc292d250 100644 --- a/src/providers/twitch/api/Helix.hpp +++ b/src/providers/twitch/api/Helix.hpp @@ -420,7 +420,7 @@ struct HelixBadgeSet { struct HelixGlobalBadges { std::vector data; - HelixGlobalBadges() = default; + explicit HelixGlobalBadges(const QJsonObject &jsonObject) { const auto &data = jsonObject.value("data").toArray(); From 85c35177bf252eeb2f1825b67d74d4068db226e8 Mon Sep 17 00:00:00 2001 From: Rasmus Karlsson Date: Sun, 16 Apr 2023 09:20:50 +0200 Subject: [PATCH 22/31] nit: rename badges member `data` to `badgeSets` The Helix API calls it data, but for us it makes more sense to call it `badgeSets` --- src/providers/twitch/TwitchBadges.cpp | 2 +- src/providers/twitch/TwitchChannel.cpp | 2 +- src/providers/twitch/api/Helix.hpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/providers/twitch/TwitchBadges.cpp b/src/providers/twitch/TwitchBadges.cpp index 95d678a9ddd..7d7f29289c2 100644 --- a/src/providers/twitch/TwitchBadges.cpp +++ b/src/providers/twitch/TwitchBadges.cpp @@ -35,7 +35,7 @@ void TwitchBadges::loadTwitchBadges() auto globalBadges = HelixGlobalBadges{result}; auto badgeSets = this->badgeSets_.access(); - for (const auto &badgeSet : globalBadges.data) + for (const auto &badgeSet : globalBadges.badgeSets) { const auto &setID = badgeSet.setID; for (const auto &version : badgeSet.versions) diff --git a/src/providers/twitch/TwitchChannel.cpp b/src/providers/twitch/TwitchChannel.cpp index 9ccb1576cb6..d0ff6364053 100644 --- a/src/providers/twitch/TwitchChannel.cpp +++ b/src/providers/twitch/TwitchChannel.cpp @@ -1294,7 +1294,7 @@ void TwitchChannel::refreshBadges() auto channelBadges = HelixChannelBadges{result}; auto badgeSets = this->badgeSets_.access(); - for (const auto &badgeSet : channelBadges.data) + for (const auto &badgeSet : channelBadges.badgeSets) { const auto &setID = badgeSet.setID; for (const auto &version : badgeSet.versions) diff --git a/src/providers/twitch/api/Helix.hpp b/src/providers/twitch/api/Helix.hpp index 80cc292d250..f3286a72903 100644 --- a/src/providers/twitch/api/Helix.hpp +++ b/src/providers/twitch/api/Helix.hpp @@ -419,14 +419,14 @@ struct HelixBadgeSet { }; struct HelixGlobalBadges { - std::vector data; + std::vector badgeSets; explicit HelixGlobalBadges(const QJsonObject &jsonObject) { const auto &data = jsonObject.value("data").toArray(); for (const auto &set : data) { - this->data.emplace_back(set.toObject()); + this->badgeSets.emplace_back(set.toObject()); } } }; From 3a84760a0f11ab140c7a66ea2ec6d68fc7be3405 Mon Sep 17 00:00:00 2001 From: Rasmus Karlsson Date: Sun, 16 Apr 2023 09:24:09 +0200 Subject: [PATCH 23/31] nit: Change the rare helix error cases to be warnings also include identifiers in the message itself to make it more identifiable --- src/providers/twitch/api/Helix.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/providers/twitch/api/Helix.cpp b/src/providers/twitch/api/Helix.cpp index b73347c2030..ab37e2e8694 100644 --- a/src/providers/twitch/api/Helix.cpp +++ b/src/providers/twitch/api/Helix.cpp @@ -2501,9 +2501,9 @@ void Helix::getGlobalBadges( break; default: { - qCDebug(chatterinoTwitch) - << "Unhandled error data:" << result.status() - << result.getData() << obj; + qCWarning(chatterinoTwitch) + << "Helix global badges, unhandled error data:" + << result.status() << result.getData() << obj; failureCallback(Error::Unknown, message); } break; @@ -2549,9 +2549,9 @@ void Helix::getChannelBadges( break; default: { - qCDebug(chatterinoTwitch) - << "Unhandled error data:" << result.status() - << result.getData() << obj; + qCWarning(chatterinoTwitch) + << "Helix channel badges, unhandled error data:" + << result.status() << result.getData() << obj; failureCallback(Error::Unknown, message); } break; From 36722162fd3da4ffe7f6c587a5851399ecf285e2 Mon Sep 17 00:00:00 2001 From: Rasmus Karlsson Date: Sun, 16 Apr 2023 11:05:12 +0200 Subject: [PATCH 24/31] nit: add space inbetween using & the makeRequest/variable definitions --- src/providers/twitch/api/Helix.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/providers/twitch/api/Helix.cpp b/src/providers/twitch/api/Helix.cpp index ab37e2e8694..cb6d125f8c0 100644 --- a/src/providers/twitch/api/Helix.cpp +++ b/src/providers/twitch/api/Helix.cpp @@ -2475,6 +2475,7 @@ void Helix::getGlobalBadges( FailureCallback failureCallback) { using Error = HelixGetGlobalBadgesError; + this->makeRequest("chat/badges/global", QUrlQuery()) .type(NetworkRequestType::Get) .onSuccess([successCallback](auto result) -> Outcome { @@ -2519,6 +2520,7 @@ void Helix::getChannelBadges( FailureCallback failureCallback) { using Error = HelixGetChannelBadgesError; + QUrlQuery urlQuery; urlQuery.addQueryItem("broadcaster_id", broadcasterID); From 8ccfb99ff817d737e13ed0a3a47ce7574565d137 Mon Sep 17 00:00:00 2001 From: Rasmus Karlsson Date: Sun, 16 Apr 2023 11:05:32 +0200 Subject: [PATCH 25/31] nit: don't specify the network request type to get get is already the default request type if one is not specified (see NetworkRequest.hpp) --- src/providers/twitch/api/Helix.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/providers/twitch/api/Helix.cpp b/src/providers/twitch/api/Helix.cpp index cb6d125f8c0..71c19175a24 100644 --- a/src/providers/twitch/api/Helix.cpp +++ b/src/providers/twitch/api/Helix.cpp @@ -2477,7 +2477,6 @@ void Helix::getGlobalBadges( using Error = HelixGetGlobalBadgesError; this->makeRequest("chat/badges/global", QUrlQuery()) - .type(NetworkRequestType::Get) .onSuccess([successCallback](auto result) -> Outcome { if (result.status() != 200) { @@ -2525,7 +2524,6 @@ void Helix::getChannelBadges( urlQuery.addQueryItem("broadcaster_id", broadcasterID); this->makeRequest("chat/badges", urlQuery) - .type(NetworkRequestType::Get) .onSuccess([successCallback](auto result) -> Outcome { if (result.status() != 200) { From 35d90f34511fd28decdfc31730942fe8e077a8bb Mon Sep 17 00:00:00 2001 From: Rasmus Karlsson Date: Sun, 16 Apr 2023 11:08:35 +0200 Subject: [PATCH 26/31] fix: we must make sure the channel is alive when channel badges finish This is done by capturing a weak pointer of the channel into the success & failure lambdas, then verifying that we're able to lock them when the request has finished --- src/providers/twitch/TwitchChannel.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/providers/twitch/TwitchChannel.cpp b/src/providers/twitch/TwitchChannel.cpp index d0ff6364053..f2849bfc362 100644 --- a/src/providers/twitch/TwitchChannel.cpp +++ b/src/providers/twitch/TwitchChannel.cpp @@ -1290,7 +1290,14 @@ void TwitchChannel::refreshBadges() getHelix()->getChannelBadges( this->roomId(), // successCallback - [this](auto result) { + [this, weak = weakOf(this)](auto result) { + auto shared = weak.lock(); + if (!shared) + { + // The channel has been closed inbetween us making the request and the request finishing + return; + } + auto channelBadges = HelixChannelBadges{result}; auto badgeSets = this->badgeSets_.access(); @@ -1314,7 +1321,14 @@ void TwitchChannel::refreshBadges() } }, // failureCallback - [this](auto error, auto message) { + [this, weak = weakOf(this)](auto error, auto message) { + auto shared = weak.lock(); + if (!shared) + { + // The channel has been closed inbetween us making the request and the request finishing + return; + } + QString errorMessage("Failed to load channel badges - "); switch (error) From ffeb297bd95ba1b16f80091a4d18674e10139c8b Mon Sep 17 00:00:00 2001 From: Rasmus Karlsson Date: Sun, 16 Apr 2023 11:10:30 +0200 Subject: [PATCH 27/31] nit: Reformat Emote creation --- src/providers/twitch/TwitchBadges.cpp | 22 ++++++++++++---------- src/providers/twitch/TwitchChannel.cpp | 19 ++++++++++--------- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/providers/twitch/TwitchBadges.cpp b/src/providers/twitch/TwitchBadges.cpp index 7d7f29289c2..71c6950f48b 100644 --- a/src/providers/twitch/TwitchBadges.cpp +++ b/src/providers/twitch/TwitchBadges.cpp @@ -40,15 +40,16 @@ void TwitchBadges::loadTwitchBadges() const auto &setID = badgeSet.setID; for (const auto &version : badgeSet.versions) { - const auto &emote = - Emote{{""}, - ImageSet{ - Image::fromUrl(version.imageURL1x), - Image::fromUrl(version.imageURL2x, .5), - Image::fromUrl(version.imageURL4x, .25), - }, - Tooltip{version.title}, - version.clickURL}; + const auto &emote = Emote{ + {""}, + ImageSet{ + Image::fromUrl(version.imageURL1x), + Image::fromUrl(version.imageURL2x, .5), + Image::fromUrl(version.imageURL4x, .25), + }, + Tooltip{version.title}, + version.clickURL, + }; (*badgeSets)[setID][version.id] = std::make_shared(emote); } @@ -117,7 +118,8 @@ void TwitchBadges::parseTwitchBadges(QJsonObject root) {versionObj.value("image_url_4x").toString()}, .25), }, Tooltip{versionObj.value("title").toString()}, - Url{versionObj.value("click_url").toString()}}; + Url{versionObj.value("click_url").toString()}, + }; // "title" // "clickAction" diff --git a/src/providers/twitch/TwitchChannel.cpp b/src/providers/twitch/TwitchChannel.cpp index f2849bfc362..93d18b31802 100644 --- a/src/providers/twitch/TwitchChannel.cpp +++ b/src/providers/twitch/TwitchChannel.cpp @@ -1306,15 +1306,16 @@ void TwitchChannel::refreshBadges() const auto &setID = badgeSet.setID; for (const auto &version : badgeSet.versions) { - const auto &emote = - Emote{{""}, - ImageSet{ - Image::fromUrl(version.imageURL1x), - Image::fromUrl(version.imageURL2x, .5), - Image::fromUrl(version.imageURL4x, .25), - }, - Tooltip{version.title}, - version.clickURL}; + const auto &emote = Emote{ + {""}, + ImageSet{ + Image::fromUrl(version.imageURL1x), + Image::fromUrl(version.imageURL2x, .5), + Image::fromUrl(version.imageURL4x, .25), + }, + Tooltip{version.title}, + version.clickURL, + }; (*badgeSets)[setID][version.id] = std::make_shared(emote); } From f1907c964ba810c71ffa3090a327b593f1055160 Mon Sep 17 00:00:00 2001 From: Rasmus Karlsson Date: Sun, 16 Apr 2023 11:11:12 +0200 Subject: [PATCH 28/31] nit: Remove const ref in emote creation --- src/providers/twitch/TwitchChannel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/providers/twitch/TwitchChannel.cpp b/src/providers/twitch/TwitchChannel.cpp index 93d18b31802..dcaf00dc861 100644 --- a/src/providers/twitch/TwitchChannel.cpp +++ b/src/providers/twitch/TwitchChannel.cpp @@ -1306,7 +1306,7 @@ void TwitchChannel::refreshBadges() const auto &setID = badgeSet.setID; for (const auto &version : badgeSet.versions) { - const auto &emote = Emote{ + auto emote = Emote{ {""}, ImageSet{ Image::fromUrl(version.imageURL1x), From f6c855b9d0f789089b755a432dedac9d86115d18 Mon Sep 17 00:00:00 2001 From: Rasmus Karlsson Date: Sun, 16 Apr 2023 11:11:39 +0200 Subject: [PATCH 29/31] nit: add back scale for 1x url --- src/providers/twitch/TwitchBadges.cpp | 2 +- src/providers/twitch/TwitchChannel.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/providers/twitch/TwitchBadges.cpp b/src/providers/twitch/TwitchBadges.cpp index 71c6950f48b..de0c513d012 100644 --- a/src/providers/twitch/TwitchBadges.cpp +++ b/src/providers/twitch/TwitchBadges.cpp @@ -43,7 +43,7 @@ void TwitchBadges::loadTwitchBadges() const auto &emote = Emote{ {""}, ImageSet{ - Image::fromUrl(version.imageURL1x), + Image::fromUrl(version.imageURL1x, 1), Image::fromUrl(version.imageURL2x, .5), Image::fromUrl(version.imageURL4x, .25), }, diff --git a/src/providers/twitch/TwitchChannel.cpp b/src/providers/twitch/TwitchChannel.cpp index dcaf00dc861..569ee170c66 100644 --- a/src/providers/twitch/TwitchChannel.cpp +++ b/src/providers/twitch/TwitchChannel.cpp @@ -1309,7 +1309,7 @@ void TwitchChannel::refreshBadges() auto emote = Emote{ {""}, ImageSet{ - Image::fromUrl(version.imageURL1x), + Image::fromUrl(version.imageURL1x, 1), Image::fromUrl(version.imageURL2x, .5), Image::fromUrl(version.imageURL4x, .25), }, From ef89d7c76b0904ff31babb45424bc6569c9cd66f Mon Sep 17 00:00:00 2001 From: Rasmus Karlsson Date: Sun, 16 Apr 2023 11:12:43 +0200 Subject: [PATCH 30/31] nit: keep `EmoteName{}` for specifying an empty emote name --- src/providers/twitch/TwitchBadges.cpp | 2 +- src/providers/twitch/TwitchChannel.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/providers/twitch/TwitchBadges.cpp b/src/providers/twitch/TwitchBadges.cpp index de0c513d012..de9b45f5bb8 100644 --- a/src/providers/twitch/TwitchBadges.cpp +++ b/src/providers/twitch/TwitchBadges.cpp @@ -41,7 +41,7 @@ void TwitchBadges::loadTwitchBadges() for (const auto &version : badgeSet.versions) { const auto &emote = Emote{ - {""}, + EmoteName{}, ImageSet{ Image::fromUrl(version.imageURL1x, 1), Image::fromUrl(version.imageURL2x, .5), diff --git a/src/providers/twitch/TwitchChannel.cpp b/src/providers/twitch/TwitchChannel.cpp index 569ee170c66..1cdcdbd9387 100644 --- a/src/providers/twitch/TwitchChannel.cpp +++ b/src/providers/twitch/TwitchChannel.cpp @@ -1307,7 +1307,7 @@ void TwitchChannel::refreshBadges() for (const auto &version : badgeSet.versions) { auto emote = Emote{ - {""}, + EmoteName{}, ImageSet{ Image::fromUrl(version.imageURL1x, 1), Image::fromUrl(version.imageURL2x, .5), From 1f310770808b08c999f19371ea5e65d4bccd60a6 Mon Sep 17 00:00:00 2001 From: Rasmus Karlsson Date: Sun, 16 Apr 2023 11:13:46 +0200 Subject: [PATCH 31/31] nit: Don't recreate the global badges --- src/providers/twitch/TwitchBadges.cpp | 3 +-- src/providers/twitch/TwitchChannel.cpp | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/providers/twitch/TwitchBadges.cpp b/src/providers/twitch/TwitchBadges.cpp index de9b45f5bb8..daf782f2918 100644 --- a/src/providers/twitch/TwitchBadges.cpp +++ b/src/providers/twitch/TwitchBadges.cpp @@ -31,8 +31,7 @@ void TwitchBadges::loadTwitchBadges() assert(this->loaded_ == false); getHelix()->getGlobalBadges( - [this](auto result) { - auto globalBadges = HelixGlobalBadges{result}; + [this](auto globalBadges) { auto badgeSets = this->badgeSets_.access(); for (const auto &badgeSet : globalBadges.badgeSets) diff --git a/src/providers/twitch/TwitchChannel.cpp b/src/providers/twitch/TwitchChannel.cpp index 1cdcdbd9387..4a81da24387 100644 --- a/src/providers/twitch/TwitchChannel.cpp +++ b/src/providers/twitch/TwitchChannel.cpp @@ -1290,7 +1290,7 @@ void TwitchChannel::refreshBadges() getHelix()->getChannelBadges( this->roomId(), // successCallback - [this, weak = weakOf(this)](auto result) { + [this, weak = weakOf(this)](auto channelBadges) { auto shared = weak.lock(); if (!shared) { @@ -1298,7 +1298,6 @@ void TwitchChannel::refreshBadges() return; } - auto channelBadges = HelixChannelBadges{result}; auto badgeSets = this->badgeSets_.access(); for (const auto &badgeSet : channelBadges.badgeSets)