mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
Migrate to the new Get Channel Followers Helix endpoint, fixing follower count not showing up in usercards (#4809)
This commit is contained in:
parent
896f12c814
commit
116af46004
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
## Unversioned
|
## Unversioned
|
||||||
|
|
||||||
|
- Minor: Migrate to the new Get Channel Followers Helix endpoint, fixing follower count not showing up in usercards. (#4809)
|
||||||
- Dev: Temporarily disable High DPI scaling on Qt6 builds on Windows. (#4767)
|
- Dev: Temporarily disable High DPI scaling on Qt6 builds on Windows. (#4767)
|
||||||
|
|
||||||
## 2.4.5
|
## 2.4.5
|
||||||
|
|
|
@ -31,17 +31,12 @@ public:
|
||||||
HelixFailureCallback failureCallback),
|
HelixFailureCallback failureCallback),
|
||||||
(override));
|
(override));
|
||||||
|
|
||||||
MOCK_METHOD(void, fetchUsersFollows,
|
MOCK_METHOD(
|
||||||
(QString fromId, QString toId,
|
void, getChannelFollowers,
|
||||||
ResultCallback<HelixUsersFollowsResponse> successCallback,
|
(QString broadcasterID,
|
||||||
HelixFailureCallback failureCallback),
|
ResultCallback<HelixGetChannelFollowersResponse> successCallback,
|
||||||
(override));
|
std::function<void(QString)> failureCallback),
|
||||||
|
(override));
|
||||||
MOCK_METHOD(void, getUserFollowers,
|
|
||||||
(QString userId,
|
|
||||||
ResultCallback<HelixUsersFollowsResponse> successCallback,
|
|
||||||
HelixFailureCallback failureCallback),
|
|
||||||
(override));
|
|
||||||
|
|
||||||
MOCK_METHOD(void, fetchStreams,
|
MOCK_METHOD(void, fetchStreams,
|
||||||
(QStringList userIds, QStringList userLogins,
|
(QStringList userIds, QStringList userLogins,
|
||||||
|
|
|
@ -126,52 +126,43 @@ void Helix::getUserById(QString userId,
|
||||||
failureCallback);
|
failureCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Helix::fetchUsersFollows(
|
void Helix::getChannelFollowers(
|
||||||
QString fromId, QString toId,
|
QString broadcasterID,
|
||||||
ResultCallback<HelixUsersFollowsResponse> successCallback,
|
ResultCallback<HelixGetChannelFollowersResponse> successCallback,
|
||||||
HelixFailureCallback failureCallback)
|
std::function<void(QString)> failureCallback)
|
||||||
{
|
{
|
||||||
assert(!fromId.isEmpty() || !toId.isEmpty());
|
assert(!broadcasterID.isEmpty());
|
||||||
|
|
||||||
QUrlQuery urlQuery;
|
QUrlQuery urlQuery;
|
||||||
|
urlQuery.addQueryItem("broadcaster_id", broadcasterID);
|
||||||
if (!fromId.isEmpty())
|
|
||||||
{
|
|
||||||
urlQuery.addQueryItem("from_id", fromId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!toId.isEmpty())
|
|
||||||
{
|
|
||||||
urlQuery.addQueryItem("to_id", toId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: set on success and on error
|
// TODO: set on success and on error
|
||||||
this->makeGet("users/follows", urlQuery)
|
this->makeGet("channels/followers", urlQuery)
|
||||||
.onSuccess([successCallback, failureCallback](auto result) -> Outcome {
|
.onSuccess([successCallback, failureCallback](auto result) -> Outcome {
|
||||||
auto root = result.parseJson();
|
auto root = result.parseJson();
|
||||||
if (root.empty())
|
if (root.empty())
|
||||||
{
|
{
|
||||||
failureCallback();
|
failureCallback("Bad JSON response");
|
||||||
return Failure;
|
return Failure;
|
||||||
}
|
}
|
||||||
successCallback(HelixUsersFollowsResponse(root));
|
successCallback(HelixGetChannelFollowersResponse(root));
|
||||||
return Success;
|
return Success;
|
||||||
})
|
})
|
||||||
.onError([failureCallback](auto /*result*/) {
|
.onError([failureCallback](auto result) {
|
||||||
// TODO: make better xd
|
auto root = result.parseJson();
|
||||||
failureCallback();
|
if (root.empty())
|
||||||
|
{
|
||||||
|
failureCallback("Unknown error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Forward "message" from Twitch
|
||||||
|
HelixError error(root);
|
||||||
|
failureCallback(error.message);
|
||||||
})
|
})
|
||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Helix::getUserFollowers(
|
|
||||||
QString userId, ResultCallback<HelixUsersFollowsResponse> successCallback,
|
|
||||||
HelixFailureCallback failureCallback)
|
|
||||||
{
|
|
||||||
this->fetchUsersFollows("", std::move(userId), std::move(successCallback),
|
|
||||||
std::move(failureCallback));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Helix::fetchStreams(
|
void Helix::fetchStreams(
|
||||||
QStringList userIds, QStringList userLogins,
|
QStringList userIds, QStringList userLogins,
|
||||||
ResultCallback<std::vector<HelixStream>> successCallback,
|
ResultCallback<std::vector<HelixStream>> successCallback,
|
||||||
|
|
|
@ -45,44 +45,12 @@ struct HelixUser {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HelixUsersFollowsRecord {
|
struct HelixGetChannelFollowersResponse {
|
||||||
QString fromId;
|
|
||||||
QString fromName;
|
|
||||||
QString toId;
|
|
||||||
QString toName;
|
|
||||||
QString followedAt; // date time object
|
|
||||||
|
|
||||||
HelixUsersFollowsRecord()
|
|
||||||
: fromId("")
|
|
||||||
, fromName("")
|
|
||||||
, toId("")
|
|
||||||
, toName("")
|
|
||||||
, followedAt("")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit HelixUsersFollowsRecord(QJsonObject jsonObject)
|
|
||||||
: fromId(jsonObject.value("from_id").toString())
|
|
||||||
, fromName(jsonObject.value("from_name").toString())
|
|
||||||
, toId(jsonObject.value("to_id").toString())
|
|
||||||
, toName(jsonObject.value("to_name").toString())
|
|
||||||
, followedAt(jsonObject.value("followed_at").toString())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct HelixUsersFollowsResponse {
|
|
||||||
int total;
|
int total;
|
||||||
std::vector<HelixUsersFollowsRecord> data;
|
|
||||||
explicit HelixUsersFollowsResponse(QJsonObject jsonObject)
|
explicit HelixGetChannelFollowersResponse(const QJsonObject &jsonObject)
|
||||||
: total(jsonObject.value("total").toInt())
|
: total(jsonObject.value("total").toInt())
|
||||||
{
|
{
|
||||||
const auto &jsonData = jsonObject.value("data").toArray();
|
|
||||||
std::transform(jsonData.begin(), jsonData.end(),
|
|
||||||
std::back_inserter(this->data),
|
|
||||||
[](const QJsonValue &record) {
|
|
||||||
return HelixUsersFollowsRecord(record.toObject());
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -720,6 +688,22 @@ enum class HelixGetGlobalBadgesError {
|
||||||
Forwarded,
|
Forwarded,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct HelixError {
|
||||||
|
/// Text version of the HTTP error that happened (e.g. Bad Request)
|
||||||
|
QString error;
|
||||||
|
/// Number version of the HTTP error that happened (e.g. 400)
|
||||||
|
int status;
|
||||||
|
/// The error message string
|
||||||
|
QString message;
|
||||||
|
|
||||||
|
explicit HelixError(const QJsonObject &json)
|
||||||
|
: error(json["error"].toString())
|
||||||
|
, status(json["status"].toInt())
|
||||||
|
, message(json["message"].toString())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
using HelixGetChannelBadgesError = HelixGetGlobalBadgesError;
|
using HelixGetChannelBadgesError = HelixGetGlobalBadgesError;
|
||||||
|
|
||||||
class IHelix
|
class IHelix
|
||||||
|
@ -740,16 +724,11 @@ public:
|
||||||
ResultCallback<HelixUser> successCallback,
|
ResultCallback<HelixUser> successCallback,
|
||||||
HelixFailureCallback failureCallback) = 0;
|
HelixFailureCallback failureCallback) = 0;
|
||||||
|
|
||||||
// https://dev.twitch.tv/docs/api/reference#get-users-follows
|
// https://dev.twitch.tv/docs/api/reference/#get-channel-followers
|
||||||
virtual void fetchUsersFollows(
|
virtual void getChannelFollowers(
|
||||||
QString fromId, QString toId,
|
QString broadcasterID,
|
||||||
ResultCallback<HelixUsersFollowsResponse> successCallback,
|
ResultCallback<HelixGetChannelFollowersResponse> successCallback,
|
||||||
HelixFailureCallback failureCallback) = 0;
|
std::function<void(QString)> failureCallback) = 0;
|
||||||
|
|
||||||
virtual void getUserFollowers(
|
|
||||||
QString userId,
|
|
||||||
ResultCallback<HelixUsersFollowsResponse> successCallback,
|
|
||||||
HelixFailureCallback failureCallback) = 0;
|
|
||||||
|
|
||||||
// https://dev.twitch.tv/docs/api/reference#get-streams
|
// https://dev.twitch.tv/docs/api/reference#get-streams
|
||||||
virtual void fetchStreams(
|
virtual void fetchStreams(
|
||||||
|
@ -1064,16 +1043,11 @@ public:
|
||||||
void getUserById(QString userId, ResultCallback<HelixUser> successCallback,
|
void getUserById(QString userId, ResultCallback<HelixUser> successCallback,
|
||||||
HelixFailureCallback failureCallback) final;
|
HelixFailureCallback failureCallback) final;
|
||||||
|
|
||||||
// https://dev.twitch.tv/docs/api/reference#get-users-follows
|
// https://dev.twitch.tv/docs/api/reference/#get-channel-followers
|
||||||
void fetchUsersFollows(
|
void getChannelFollowers(
|
||||||
QString fromId, QString toId,
|
QString broadcasterID,
|
||||||
ResultCallback<HelixUsersFollowsResponse> successCallback,
|
ResultCallback<HelixGetChannelFollowersResponse> successCallback,
|
||||||
HelixFailureCallback failureCallback) final;
|
std::function<void(QString)> failureCallback) final;
|
||||||
|
|
||||||
void getUserFollowers(
|
|
||||||
QString userId,
|
|
||||||
ResultCallback<HelixUsersFollowsResponse> successCallback,
|
|
||||||
HelixFailureCallback failureCallback) final;
|
|
||||||
|
|
||||||
// https://dev.twitch.tv/docs/api/reference#get-streams
|
// https://dev.twitch.tv/docs/api/reference#get-streams
|
||||||
void fetchStreams(QStringList userIds, QStringList userLogins,
|
void fetchStreams(QStringList userIds, QStringList userLogins,
|
||||||
|
|
|
@ -817,7 +817,7 @@ void UserInfoPopup::updateUserData()
|
||||||
this->loadAvatar(user.profileImageUrl);
|
this->loadAvatar(user.profileImageUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
getHelix()->getUserFollowers(
|
getHelix()->getChannelFollowers(
|
||||||
user.id,
|
user.id,
|
||||||
[this, hack](const auto &followers) {
|
[this, hack](const auto &followers) {
|
||||||
if (!hack.lock())
|
if (!hack.lock())
|
||||||
|
@ -827,8 +827,9 @@ void UserInfoPopup::updateUserData()
|
||||||
this->ui_.followerCountLabel->setText(
|
this->ui_.followerCountLabel->setText(
|
||||||
TEXT_FOLLOWERS.arg(localizeNumbers(followers.total)));
|
TEXT_FOLLOWERS.arg(localizeNumbers(followers.total)));
|
||||||
},
|
},
|
||||||
[] {
|
[](const auto &errorMessage) {
|
||||||
// on failure
|
qCWarning(chatterinoTwitch)
|
||||||
|
<< "Error getting followers:" << errorMessage;
|
||||||
});
|
});
|
||||||
|
|
||||||
// get ignore state
|
// get ignore state
|
||||||
|
|
Loading…
Reference in a new issue