feat: add filter for external badges (#6709)
Co-authored-by: Ava Chow <github@achow101.com> Reviewed-by: Nerixyz <nerixdev@outlook.de>
This commit is contained in:
@@ -12,6 +12,7 @@ namespace chatterino::filters {
|
||||
|
||||
const QMap<QString, Type> MESSAGE_TYPING_CONTEXT{
|
||||
{"author.badges", Type::StringList},
|
||||
{"author.external_badges", Type::StringList},
|
||||
{"author.color", Type::Color},
|
||||
{"author.name", Type::String},
|
||||
{"author.user_id", Type::String},
|
||||
@@ -49,16 +50,17 @@ ContextMap buildContextMap(const MessagePtr &m, chatterino::Channel *channel)
|
||||
{
|
||||
auto watchingChannel = getApp()->getTwitch()->getWatchingChannel().get();
|
||||
|
||||
/*
|
||||
* Looking to add a new identifier to filters? Here's what to do:
|
||||
* 1. Update validIdentifiersMap in Tokenizer.cpp
|
||||
/*
|
||||
* Looking to add a new identifier to filters? Here's what to do:
|
||||
* 1. Update VALID_IDENTIFIERS_MAP in Tokenizer.cpp
|
||||
* 2. Add the identifier to the list below
|
||||
* 3. Add the type of the identifier to MESSAGE_TYPING_CONTEXT in Filter.hpp
|
||||
* 3. Add the type of the identifier to MESSAGE_TYPING_CONTEXT at the top of this file
|
||||
* 4. Add the value for the identifier to the ContextMap returned by this function
|
||||
*
|
||||
*
|
||||
* List of identifiers:
|
||||
*
|
||||
* author.badges
|
||||
* author.external_badges
|
||||
* author.color
|
||||
* author.name
|
||||
* author.user_id
|
||||
@@ -121,6 +123,7 @@ ContextMap buildContextMap(const MessagePtr &m, chatterino::Channel *channel)
|
||||
}
|
||||
ContextMap vars = {
|
||||
{"author.badges", std::move(badges)},
|
||||
{"author.external_badges", m->externalBadges},
|
||||
{"author.color", m->usernameColor},
|
||||
{"author.name", m->displayName},
|
||||
{"author.user_id", m->userID},
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace chatterino::filters {
|
||||
|
||||
const QMap<QString, QString> VALID_IDENTIFIERS_MAP{
|
||||
{"author.badges", "author badges"},
|
||||
{"author.external_badges", "author external badges"},
|
||||
{"author.color", "author color"},
|
||||
{"author.name", "author name"},
|
||||
{"author.user_id", "author user id"},
|
||||
|
||||
@@ -132,6 +132,8 @@ QJsonObject Message::toJson() const
|
||||
}
|
||||
msg["twitchBadgeInfos"_L1] = twitchBadgeInfos;
|
||||
|
||||
msg["externalBadges"_L1] = QJsonArray::fromStringList(this->externalBadges);
|
||||
|
||||
if (this->highlightColor)
|
||||
{
|
||||
msg["highlightColor"_L1] = this->highlightColor->name(QColor::HexArgb);
|
||||
|
||||
@@ -61,6 +61,13 @@ struct Message {
|
||||
/// Map of extra data associated with each Twitch badge
|
||||
std::unordered_map<QString, QString> twitchBadgeInfos;
|
||||
|
||||
/// List of external badges associated with this message
|
||||
/// The badge should follow the following format: "provider:badgename". e.g.:
|
||||
/// - betterttv:pro
|
||||
/// - frankerfacez:mod
|
||||
/// - 7tv:sub
|
||||
QStringList externalBadges;
|
||||
|
||||
std::shared_ptr<QColor> highlightColor;
|
||||
// Each reply holds a reference to the thread. When every reply is dropped,
|
||||
// the reply thread will be cleaned up by the TwitchChannel.
|
||||
|
||||
@@ -2472,6 +2472,9 @@ void MessageBuilder::appendChatterinoBadges(const QString &userID)
|
||||
{
|
||||
this->emplace<BadgeElement>(*badge,
|
||||
MessageElementFlag::BadgeChatterino);
|
||||
|
||||
/// e.g. "chatterino:Chatterino Top donator"
|
||||
this->message().externalBadges.emplace_back((*badge)->name.string);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2482,6 +2485,9 @@ void MessageBuilder::appendFfzBadges(TwitchChannel *twitchChannel,
|
||||
{
|
||||
this->emplace<FfzBadgeElement>(
|
||||
badge.emote, MessageElementFlag::BadgeFfz, badge.color);
|
||||
|
||||
/// e.g. "frankerfacez:subwoofer"
|
||||
this->message().externalBadges.emplace_back(badge.emote->name.string);
|
||||
}
|
||||
|
||||
if (twitchChannel == nullptr)
|
||||
@@ -2493,6 +2499,9 @@ void MessageBuilder::appendFfzBadges(TwitchChannel *twitchChannel,
|
||||
{
|
||||
this->emplace<FfzBadgeElement>(
|
||||
badge.emote, MessageElementFlag::BadgeFfz, badge.color);
|
||||
|
||||
/// e.g. "frankerfacez:subwoofer"
|
||||
this->message().externalBadges.emplace_back(badge.emote->name.string);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2501,6 +2510,9 @@ void MessageBuilder::appendBttvBadges(const QString &userID)
|
||||
if (auto badge = getApp()->getBttvBadges()->getBadge({userID}))
|
||||
{
|
||||
this->emplace<BadgeElement>(*badge, MessageElementFlag::BadgeBttv);
|
||||
|
||||
/// e.g. "betterttv:Pro Subscriber"
|
||||
this->message().externalBadges.emplace_back((*badge)->name.string);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2509,6 +2521,9 @@ void MessageBuilder::appendSeventvBadges(const QString &userID)
|
||||
if (auto badge = getApp()->getSeventvBadges()->getBadge({userID}))
|
||||
{
|
||||
this->emplace<BadgeElement>(*badge, MessageElementFlag::BadgeSevenTV);
|
||||
|
||||
/// e.g. "7tv:NNYS 2024"
|
||||
this->message().externalBadges.emplace_back((*badge)->name.string);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
#include "messages/Emote.hpp"
|
||||
#include "messages/Image.hpp"
|
||||
|
||||
using namespace Qt::StringLiterals;
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
QString BttvBadges::idForBadge(const QJsonObject &badgeJson) const
|
||||
@@ -11,10 +13,10 @@ QString BttvBadges::idForBadge(const QJsonObject &badgeJson) const
|
||||
}
|
||||
|
||||
EmotePtr BttvBadges::createBadge(const QString &id,
|
||||
const QJsonObject & /* badgeJson */) const
|
||||
const QJsonObject & /*badgeJson*/) const
|
||||
{
|
||||
auto emote = Emote{
|
||||
.name = EmoteName{},
|
||||
.name = EmoteName{u"betterttv:pro"_s},
|
||||
.images = ImageSet(Image::fromUrl(Url{id}, 18.0 / 72.0)),
|
||||
.tooltip = Tooltip{"BTTV Pro"},
|
||||
.homePage = Url{},
|
||||
|
||||
@@ -48,8 +48,9 @@ void ChatterinoBadges::loadChatterinoBadges()
|
||||
// The sizes for the images are only an estimation, there might
|
||||
// be badges with different sizes.
|
||||
constexpr QSize baseSize(18, 18);
|
||||
auto tooltip = jsonBadge.value("tooltip").toString();
|
||||
auto emote = Emote{
|
||||
.name = EmoteName{},
|
||||
.name = EmoteName{u"chatterino:" % tooltip},
|
||||
.images =
|
||||
ImageSet{
|
||||
Image::fromUrl(
|
||||
@@ -62,7 +63,7 @@ void ChatterinoBadges::loadChatterinoBadges()
|
||||
Url{jsonBadge.value("image3").toString()}, 0.25,
|
||||
baseSize * 4),
|
||||
},
|
||||
.tooltip = Tooltip{jsonBadge.value("tooltip").toString()},
|
||||
.tooltip = Tooltip{tooltip},
|
||||
.homePage = Url{},
|
||||
};
|
||||
|
||||
|
||||
@@ -66,7 +66,11 @@ void FfzBadges::load()
|
||||
jsonBadge["height"].toInt(18));
|
||||
|
||||
auto emote = Emote{
|
||||
.name = EmoteName{},
|
||||
.name =
|
||||
EmoteName{
|
||||
u"frankerfacez:" %
|
||||
jsonBadge.value("name").toString(),
|
||||
},
|
||||
.images =
|
||||
ImageSet{
|
||||
Image::fromUrl(
|
||||
@@ -82,13 +86,11 @@ void FfzBadges::load()
|
||||
.homePage = Url{},
|
||||
};
|
||||
|
||||
Badge badge;
|
||||
|
||||
int badgeID = jsonBadge.value("id").toInt();
|
||||
|
||||
this->badges[badgeID] = Badge{
|
||||
std::make_shared<const Emote>(std::move(emote)),
|
||||
QColor(jsonBadge.value("color").toString()),
|
||||
.emote = std::make_shared<const Emote>(std::move(emote)),
|
||||
.color = QColor(jsonBadge.value("color").toString()),
|
||||
};
|
||||
|
||||
// Find users with this badge
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "util/ThreadGuard.hpp"
|
||||
|
||||
#include <QColor>
|
||||
#include <QString>
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "providers/seventv/SeventvBadges.hpp"
|
||||
|
||||
#include "messages/Emote.hpp"
|
||||
#include "messages/Image.hpp"
|
||||
#include "messages/Image.hpp" // IWYU pragma: keep
|
||||
#include "providers/seventv/SeventvEmotes.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
@@ -15,7 +15,9 @@ EmotePtr SeventvBadges::createBadge(const QString &id,
|
||||
const QJsonObject &badgeJson) const
|
||||
{
|
||||
auto emote = Emote{
|
||||
.name = EmoteName{},
|
||||
// We utilize the "emote" "name" for filtering badges, and expect
|
||||
// the format to be "7tv:badge name" (e.g. "7tv:NNYS 2024")
|
||||
.name = EmoteName{u"7tv:" % badgeJson["name"].toString()},
|
||||
.images = SeventvEmotes::createImageSet(badgeJson, true),
|
||||
.tooltip = Tooltip{badgeJson["tooltip"].toString()},
|
||||
.homePage = Url{},
|
||||
|
||||
Reference in New Issue
Block a user