custom ffz moderator badges (#827)

This commit is contained in:
pphop 2018-10-26 00:53:03 +05:00 committed by fourtf
parent c13a88e3b6
commit 3c9bcd581a
6 changed files with 136 additions and 3 deletions

View file

@ -263,7 +263,8 @@ SOURCES += \
src/common/UsernameSet.cpp \ src/common/UsernameSet.cpp \
src/widgets/settingspages/AdvancedPage.cpp \ src/widgets/settingspages/AdvancedPage.cpp \
src/util/IncognitoBrowser.cpp \ src/util/IncognitoBrowser.cpp \
src/widgets/splits/ClosedSplits.cpp src/widgets/splits/ClosedSplits.cpp \
src/providers/ffz/FfzModBadge.cpp
HEADERS += \ HEADERS += \
src/Application.hpp \ src/Application.hpp \
@ -466,7 +467,8 @@ HEADERS += \
src/common/UsernameSet.hpp \ src/common/UsernameSet.hpp \
src/widgets/settingspages/AdvancedPage.hpp \ src/widgets/settingspages/AdvancedPage.hpp \
src/util/IncognitoBrowser.hpp \ src/util/IncognitoBrowser.hpp \
src/widgets/splits/ClosedSplits.hpp src/widgets/splits/ClosedSplits.hpp \
src/providers/ffz/FfzModBadge.hpp
RESOURCES += \ RESOURCES += \
resources/resources.qrc \ resources/resources.qrc \

View file

@ -0,0 +1,86 @@
#include "FfzModBadge.hpp"
#include <QBuffer>
#include <QImageReader>
#include <QJsonObject>
#include <QPainter>
#include <QString>
#include "common/NetworkRequest.hpp"
#include "common/Outcome.hpp"
#include "messages/Emote.hpp"
namespace chatterino {
FfzModBadge::FfzModBadge(const QString &channelName)
: channelName_(channelName)
{
}
void FfzModBadge::loadCustomModBadge()
{
static QString partialUrl("https://api.frankerfacez.com/v1/_room/");
QString url = partialUrl + channelName_;
NetworkRequest req(url);
req.setCaller(QThread::currentThread());
req.onSuccess([this](auto result) -> Outcome {
auto root = result.parseJson();
auto modBadgeUrlField =
root.value("room").toObject().value("moderator_badge");
if (modBadgeUrlField.isNull())
return Failure;
auto badgeUrl = "https:" + modBadgeUrlField.toString();
/* doesnt work for some reason
auto badgeOverlay =
Image::fromUrl({"https:" + modBadgeUrlField.toString()});
auto badgeOverlayPixmap = badgeOverlay->pixmap();
if (!badgeOverlayPixmap)
return Failure;
*/
NetworkRequest getBadge(badgeUrl);
getBadge.setCaller(QThread::currentThread());
getBadge.onSuccess([this, &badgeUrl](auto result) -> Outcome {
auto data = result.getData();
QBuffer buffer(const_cast<QByteArray *>(&data));
buffer.open(QIODevice::ReadOnly);
QImageReader reader(&buffer);
if (reader.imageCount() == 0)
return Failure;
auto badgeOverlay = QPixmap::fromImageReader(&reader);
QPixmap badgePixmap(18, 18);
// the default mod badge green color
badgePixmap.fill(QColor("#34AE0A"));
QPainter painter(&badgePixmap);
QRectF rect(0, 0, 18, 18);
painter.drawPixmap(rect, badgeOverlay, rect);
auto emote = Emote{{""},
ImageSet{Image::fromPixmap(badgePixmap)},
Tooltip{"Twitch Channel Moderator"},
Url{badgeUrl}};
this->badge_ = std::make_shared<Emote>(emote);
return Success;
});
getBadge.execute();
return Success;
});
req.execute();
}
EmotePtr FfzModBadge::badge() const
{
return this->badge_;
}
} // namespace chatterino

View file

@ -0,0 +1,25 @@
#pragma once
#include <QString>
#include <boost/optional.hpp>
namespace chatterino {
struct Emote;
using EmotePtr = std::shared_ptr<const Emote>;
class FfzModBadge
{
public:
FfzModBadge(const QString &channelName);
void loadCustomModBadge();
EmotePtr badge() const;
private:
const QString channelName_;
EmotePtr badge_;
};
} // namespace chatterino

View file

@ -91,6 +91,7 @@ TwitchChannel::TwitchChannel(const QString &name,
, globalFfz_(ffz) , globalFfz_(ffz)
, bttvEmotes_(std::make_shared<EmoteMap>()) , bttvEmotes_(std::make_shared<EmoteMap>())
, ffzEmotes_(std::make_shared<EmoteMap>()) , ffzEmotes_(std::make_shared<EmoteMap>())
, ffzCustomModBadge_(name)
, mod_(false) , mod_(false)
{ {
log("[TwitchChannel:{}] Opened", name); log("[TwitchChannel:{}] Opened", name);
@ -143,6 +144,7 @@ void TwitchChannel::initialize()
{ {
this->refreshChatters(); this->refreshChatters();
this->refreshChannelEmotes(); this->refreshChannelEmotes();
this->ffzCustomModBadge_.loadCustomModBadge();
} }
bool TwitchChannel::isEmpty() const bool TwitchChannel::isEmpty() const
@ -783,4 +785,12 @@ boost::optional<EmotePtr> TwitchChannel::twitchBadge(
return boost::none; return boost::none;
} }
boost::optional<EmotePtr> TwitchChannel::ffzCustomModBadge() const
{
if (auto badge = this->ffzCustomModBadge_.badge())
return badge;
return boost::none;
}
} // namespace chatterino } // namespace chatterino

View file

@ -6,6 +6,7 @@
#include "common/Outcome.hpp" #include "common/Outcome.hpp"
#include "common/UniqueAccess.hpp" #include "common/UniqueAccess.hpp"
#include "common/UsernameSet.hpp" #include "common/UsernameSet.hpp"
#include "providers/ffz/FfzModBadge.hpp"
#include "providers/twitch/TwitchEmotes.hpp" #include "providers/twitch/TwitchEmotes.hpp"
#include <rapidjson/document.h> #include <rapidjson/document.h>
@ -84,6 +85,7 @@ public:
void refreshChannelEmotes(); void refreshChannelEmotes();
// Badges // Badges
boost::optional<EmotePtr> ffzCustomModBadge() const;
boost::optional<EmotePtr> twitchBadge(const QString &set, boost::optional<EmotePtr> twitchBadge(const QString &set,
const QString &version) const; const QString &version) const;
@ -141,6 +143,7 @@ private:
UniqueAccess<std::map<QString, std::map<QString, EmotePtr>>> UniqueAccess<std::map<QString, std::map<QString, EmotePtr>>>
badgeSets_; // "subscribers": { "0": ... "3": ... "6": ... badgeSets_; // "subscribers": { "0": ... "3": ... "6": ...
UniqueAccess<std::vector<CheerEmoteSet>> cheerEmoteSets_; UniqueAccess<std::vector<CheerEmoteSet>> cheerEmoteSets_;
FfzModBadge ffzCustomModBadge_;
bool mod_ = false; bool mod_ = false;
UniqueAccess<QString> roomID_; UniqueAccess<QString> roomID_;

View file

@ -1107,7 +1107,14 @@ void TwitchMessageBuilder::appendTwitchBadges()
} }
else if (badge == "moderator/1") else if (badge == "moderator/1")
{ {
// TODO: Implement custom FFZ moderator badge if (auto customModBadge = this->twitchChannel->ffzCustomModBadge())
{
this->emplace<EmoteElement>(
customModBadge.get(),
MessageElementFlag::BadgeChannelAuthority)
->setTooltip((*customModBadge)->tooltip.string);
continue;
}
this->emplace<ImageElement>( this->emplace<ImageElement>(
Image::fromPixmap(app->resources->twitch.moderator), Image::fromPixmap(app->resources->twitch.moderator),
MessageElementFlag::BadgeChannelAuthority) MessageElementFlag::BadgeChannelAuthority)