Use New 7TV Cosmetics System (#4512)

* feat(seventv): use new cosmetics system

* chore: add changelog entry

* fix: old `clang-format`

* fix: small suggestions pt1

* refactor: add 7tv api wrapper

* fix: small clang-tidy things

* fix: remove unused constants

* fix: old clangtidy

* refactor: rename

* fix: increase interval to 60s

* fix: newline

* fix: Twitch

* docs: add comment

* fix: remove v2 badges endpoint

* fix: deadlock

This is actually really sad.

* fix: remove api entry

* fix: old clang-format

* Sort functions in SeventvBadges.hpp/cpp

* Remove unused vector include

* Add comments to SeventvBadges.hpp functions

* Rename `addBadge` to `registerBadge`

* fix: cleanup eventloop

* ci(test): add timeout

---------

Co-authored-by: Felanbird <41973452+Felanbird@users.noreply.github.com>
Co-authored-by: Rasmus Karlsson <rasmus.karlsson@pajlada.com>
This commit is contained in:
nerix
2023-07-29 11:49:44 +02:00
committed by GitHub
parent 8cfa5e866e
commit 33fa3e0a97
25 changed files with 828 additions and 189 deletions
@@ -1,5 +1,7 @@
#include "providers/seventv/eventapi/Dispatch.hpp"
#include <QJsonArray>
#include <utility>
namespace chatterino::seventv::eventapi {
@@ -91,4 +93,45 @@ bool UserConnectionUpdateDispatch::validate() const
!this->emoteSetID.isEmpty();
}
CosmeticCreateDispatch::CosmeticCreateDispatch(const Dispatch &dispatch)
: data(dispatch.body["object"]["data"].toObject())
, kind(magic_enum::enum_cast<CosmeticKind>(
dispatch.body["object"]["kind"].toString().toStdString())
.value_or(CosmeticKind::INVALID))
{
}
bool CosmeticCreateDispatch::validate() const
{
return !this->data.empty() && this->kind != CosmeticKind::INVALID;
}
EntitlementCreateDeleteDispatch::EntitlementCreateDeleteDispatch(
const Dispatch &dispatch)
{
const auto obj = dispatch.body["object"].toObject();
this->refID = obj["ref_id"].toString();
this->kind = magic_enum::enum_cast<CosmeticKind>(
obj["kind"].toString().toStdString())
.value_or(CosmeticKind::INVALID);
const auto userConnections = obj["user"]["connections"].toArray();
for (const auto &connectionJson : userConnections)
{
const auto connection = connectionJson.toObject();
if (connection["platform"].toString() == "TWITCH")
{
this->userID = connection["id"].toString();
this->userName = connection["username"].toString();
break;
}
}
}
bool EntitlementCreateDeleteDispatch::validate() const
{
return !this->userID.isEmpty() && !this->userName.isEmpty() &&
!this->refID.isEmpty() && this->kind != CosmeticKind::INVALID;
}
} // namespace chatterino::seventv::eventapi
@@ -1,6 +1,7 @@
#pragma once
#include "providers/seventv/eventapi/Subscription.hpp"
#include "providers/seventv/SeventvCosmetics.hpp"
#include <QJsonObject>
#include <QString>
@@ -67,4 +68,26 @@ struct UserConnectionUpdateDispatch {
bool validate() const;
};
struct CosmeticCreateDispatch {
QJsonObject data;
CosmeticKind kind;
CosmeticCreateDispatch(const Dispatch &dispatch);
bool validate() const;
};
struct EntitlementCreateDeleteDispatch {
/** id of the user */
QString userID;
QString userName;
/** id of the entitlement */
QString refID;
CosmeticKind kind;
EntitlementCreateDeleteDispatch(const Dispatch &dispatch);
bool validate() const;
};
} // namespace chatterino::seventv::eventapi
@@ -102,4 +102,34 @@ QDebug &operator<<(QDebug &dbg, const ObjectIDCondition &condition)
return dbg;
}
ChannelCondition::ChannelCondition(QString twitchID)
: twitchID(std::move(twitchID))
{
}
QJsonObject ChannelCondition::encode() const
{
QJsonObject obj;
obj["ctx"] = "channel";
obj["platform"] = "TWITCH";
obj["id"] = this->twitchID;
return obj;
}
QDebug &operator<<(QDebug &dbg, const ChannelCondition &condition)
{
dbg << "{ twitchID:" << condition.twitchID << '}';
return dbg;
}
bool ChannelCondition::operator==(const ChannelCondition &rhs) const
{
return this->twitchID == rhs.twitchID;
}
bool ChannelCondition::operator!=(const ChannelCondition &rhs) const
{
return !(*this == rhs);
}
} // namespace chatterino::seventv::eventapi
@@ -12,9 +12,22 @@ namespace chatterino::seventv::eventapi {
// https://github.com/SevenTV/EventAPI/tree/ca4ff15cc42b89560fa661a76c5849047763d334#subscription-types
enum class SubscriptionType {
AnyEmoteSet,
CreateEmoteSet,
UpdateEmoteSet,
UpdateUser,
AnyCosmetic,
CreateCosmetic,
UpdateCosmetic,
DeleteCosmetic,
AnyEntitlement,
CreateEntitlement,
UpdateEntitlement,
DeleteEntitlement,
INVALID,
};
@@ -46,7 +59,19 @@ struct ObjectIDCondition {
bool operator!=(const ObjectIDCondition &rhs) const;
};
using Condition = std::variant<ObjectIDCondition>;
struct ChannelCondition {
ChannelCondition(QString twitchID);
QString twitchID;
QJsonObject encode() const;
friend QDebug &operator<<(QDebug &dbg, const ChannelCondition &condition);
bool operator==(const ChannelCondition &rhs) const;
bool operator!=(const ChannelCondition &rhs) const;
};
using Condition = std::variant<ObjectIDCondition, ChannelCondition>;
struct Subscription {
bool operator==(const Subscription &rhs) const;
@@ -70,10 +95,30 @@ constexpr magic_enum::customize::customize_t magic_enum::customize::enum_name<
using chatterino::seventv::eventapi::SubscriptionType;
switch (value)
{
case SubscriptionType::AnyEmoteSet:
return "emote_set.*";
case SubscriptionType::CreateEmoteSet:
return "emote_set.create";
case SubscriptionType::UpdateEmoteSet:
return "emote_set.update";
case SubscriptionType::UpdateUser:
return "user.update";
case SubscriptionType::AnyCosmetic:
return "cosmetic.*";
case SubscriptionType::CreateCosmetic:
return "cosmetic.create";
case SubscriptionType::UpdateCosmetic:
return "cosmetic.update";
case SubscriptionType::DeleteCosmetic:
return "cosmetic.delete";
case SubscriptionType::AnyEntitlement:
return "entitlement.*";
case SubscriptionType::CreateEntitlement:
return "entitlement.create";
case SubscriptionType::UpdateEntitlement:
return "entitlement.update";
case SubscriptionType::DeleteEntitlement:
return "entitlement.delete";
default:
return default_tag;
@@ -91,6 +136,15 @@ struct hash<chatterino::seventv::eventapi::ObjectIDCondition> {
}
};
template <>
struct hash<chatterino::seventv::eventapi::ChannelCondition> {
size_t operator()(
const chatterino::seventv::eventapi::ChannelCondition &c) const
{
return qHash(c.twitchID);
}
};
template <>
struct hash<chatterino::seventv::eventapi::Subscription> {
size_t operator()(