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
+34 -1
View File
@@ -3,7 +3,7 @@
#include "Application.hpp"
#include "common/Channel.hpp"
#include "common/Env.hpp"
#include "common/NetworkRequest.hpp"
#include "common/NetworkResult.hpp"
#include "common/Outcome.hpp"
#include "common/QLogging.hpp"
#include "controllers/accounts/AccountController.hpp"
@@ -12,6 +12,7 @@
#include "messages/MessageBuilder.hpp"
#include "providers/irc/IrcMessageBuilder.hpp"
#include "providers/IvrApi.hpp"
#include "providers/seventv/SeventvAPI.hpp"
#include "providers/twitch/api/Helix.hpp"
#include "providers/twitch/TwitchCommon.hpp"
#include "singletons/Emotes.hpp"
@@ -445,4 +446,36 @@ void TwitchAccount::autoModDeny(const QString msgID, ChannelPtr channel)
});
}
const QString &TwitchAccount::getSeventvUserID() const
{
return this->seventvUserID_;
}
void TwitchAccount::loadSeventvUserID()
{
if (this->isAnon())
{
return;
}
if (!this->seventvUserID_.isEmpty())
{
return;
}
getSeventvAPI().getUserByTwitchID(
this->getUserId(),
[this](const auto &json) {
const auto id = json["user"]["id"].toString();
if (!id.isEmpty())
{
this->seventvUserID_ = id;
}
return Success;
},
[](const auto &result) {
qCDebug(chatterinoSeventv)
<< "Failed to load 7TV user-id:" << result.formatError();
});
}
} // namespace chatterino
+10
View File
@@ -59,6 +59,12 @@ public:
const QString &getOAuthClient() const;
const QString &getUserId() const;
/**
* The Seventv user-id of the current user.
* Empty if there's no associated Seventv user with this twitch user.
*/
const QString &getSeventvUserID() const;
QColor color();
void setColor(QColor color);
@@ -98,6 +104,8 @@ public:
void autoModAllow(const QString msgID, ChannelPtr channel);
void autoModDeny(const QString msgID, ChannelPtr channel);
void loadSeventvUserID();
private:
QString oauthClient_;
QString oauthToken_;
@@ -115,6 +123,8 @@ private:
// std::map<UserId, TwitchAccountEmoteData> emotes;
UniqueAccess<TwitchAccountEmoteData> emotes_;
UniqueAccess<std::unordered_map<QString, EmoteMap>> localEmotes_;
QString seventvUserID_;
};
} // namespace chatterino
@@ -17,6 +17,7 @@ TwitchAccountManager::TwitchAccountManager()
this->currentUserChanged.connect([this] {
auto currentUser = this->getCurrent();
currentUser->loadBlocks();
currentUser->loadSeventvUserID();
});
this->accounts.itemRemoved.connect([this](const auto &acc) {
+66
View File
@@ -20,6 +20,7 @@
#include "providers/bttv/liveupdates/BttvLiveUpdateMessages.hpp"
#include "providers/RecentMessagesApi.hpp"
#include "providers/seventv/eventapi/Dispatch.hpp"
#include "providers/seventv/SeventvAPI.hpp"
#include "providers/seventv/SeventvEmotes.hpp"
#include "providers/seventv/SeventvEventAPI.hpp"
#include "providers/twitch/api/Helix.hpp"
@@ -40,6 +41,7 @@
#include <IrcConnection>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
#include <QThread>
@@ -105,6 +107,7 @@ TwitchChannel::TwitchChannel(const QString &name)
this->refreshBTTVChannelEmotes(false);
this->refreshSevenTVChannelEmotes(false);
this->joinBttvChannel();
this->listenSevenTVCosmetics();
getIApp()->getTwitchLiveController()->add(
std::dynamic_pointer_cast<TwitchChannel>(shared_from_this()));
});
@@ -248,6 +251,12 @@ TwitchChannel::~TwitchChannel()
{
getApp()->twitch->bttvLiveUpdates->partChannel(this->roomId());
}
if (getApp()->twitch->seventvEventAPI)
{
getApp()->twitch->seventvEventAPI->unsubscribeTwitchChannel(
this->roomId());
}
}
void TwitchChannel::initialize()
@@ -600,6 +609,7 @@ void TwitchChannel::sendMessage(const QString &message)
bool messageSent = false;
this->sendMessageSignal.invoke(this->getName(), parsedMessage, messageSent);
this->updateSevenTVActivity();
if (messageSent)
{
@@ -1564,4 +1574,60 @@ boost::optional<CheerEmote> TwitchChannel::cheerEmote(const QString &string)
return boost::none;
}
void TwitchChannel::updateSevenTVActivity()
{
static const QString seventvActivityUrl =
QStringLiteral("https://7tv.io/v3/users/%1/presences");
const auto currentSeventvUserID =
getApp()->accounts->twitch.getCurrent()->getSeventvUserID();
if (currentSeventvUserID.isEmpty())
{
return;
}
if (!getSettings()->enableSevenTVEventAPI ||
!getSettings()->sendSevenTVActivity)
{
return;
}
if (this->nextSeventvActivity_.isValid() &&
QDateTime::currentDateTimeUtc() < this->nextSeventvActivity_)
{
return;
}
// Make sure to not send activity again before receiving the response
this->nextSeventvActivity_ = this->nextSeventvActivity_.addSecs(300);
qCDebug(chatterinoSeventv) << "Sending activity in" << this->getName();
getSeventvAPI().updatePresence(
this->roomId(), currentSeventvUserID,
[chan = weakOf<Channel>(this)]() {
const auto self =
std::dynamic_pointer_cast<TwitchChannel>(chan.lock());
if (!self)
{
return Success;
}
self->nextSeventvActivity_ =
QDateTime::currentDateTimeUtc().addSecs(60);
return Success;
},
[](const auto &result) {
qCDebug(chatterinoSeventv)
<< "Failed to update 7TV activity:" << result.formatError();
});
}
void TwitchChannel::listenSevenTVCosmetics()
{
if (getApp()->twitch->seventvEventAPI)
{
getApp()->twitch->seventvEventAPI->subscribeTwitchChannel(
this->roomId());
}
}
} // namespace chatterino
+12
View File
@@ -254,6 +254,12 @@ private:
void showLoginMessage();
/** Joins (subscribes to) a Twitch channel for updates on BTTV. */
void joinBttvChannel() const;
/**
* Indicates an activity to 7TV in this channel for this user.
* This is done at most once every 60s.
*/
void updateSevenTVActivity();
void listenSevenTVCosmetics();
/**
* @brief Sets the live status of this Twitch channel
@@ -372,6 +378,12 @@ private:
*/
size_t seventvUserTwitchConnectionIndex_;
/**
* The next moment in time to signal activity in this channel to 7TV.
* Or: Up until this moment we don't need to send activity.
*/
QDateTime nextSeventvActivity_;
/** The platform of the last live emote update ("7TV", "BTTV", "FFZ"). */
QString lastLiveUpdateEmotePlatform_;
/** The actor name of the last live emote update. */