Merge pull request #966 from hemirt/master

Use ffz/bttv channel emotes for chatrooms
This commit is contained in:
pajlada 2019-03-02 09:31:29 +01:00 committed by GitHub
commit d739cb72d9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 156 additions and 6 deletions

View file

@ -206,6 +206,7 @@ SOURCES += \
src/widgets/splits/ClosedSplits.cpp \ src/widgets/splits/ClosedSplits.cpp \
src/providers/ffz/FfzModBadge.cpp \ src/providers/ffz/FfzModBadge.cpp \
src/widgets/settingspages/GeneralPage.cpp \ src/widgets/settingspages/GeneralPage.cpp \
src/providers/twitch/ChatroomChannel.cpp
HEADERS += \ HEADERS += \
src/Application.hpp \ src/Application.hpp \
@ -385,7 +386,8 @@ HEADERS += \
src/widgets/splits/ClosedSplits.hpp \ src/widgets/splits/ClosedSplits.hpp \
src/providers/ffz/FfzModBadge.hpp \ src/providers/ffz/FfzModBadge.hpp \
src/widgets/settingspages/GeneralPage.hpp \ src/widgets/settingspages/GeneralPage.hpp \
src/messages/HistoricMessageAppearance.hpp src/messages/HistoricMessageAppearance.hpp \
src/providers/twitch/ChatroomChannel.hpp
RESOURCES += \ RESOURCES += \
resources/resources.qrc \ resources/resources.qrc \

View file

@ -43,6 +43,11 @@ const QString &Channel::getName() const
return this->name_; return this->name_;
} }
const QString &Channel::getDisplayName() const
{
return this->getName();
}
bool Channel::isTwitchChannel() const bool Channel::isTwitchChannel() const
{ {
return this->type_ >= Type::Twitch && this->type_ < Type::TwitchEnd; return this->type_ >= Type::Twitch && this->type_ < Type::TwitchEnd;

View file

@ -47,6 +47,7 @@ public:
Type getType() const; Type getType() const;
const QString &getName() const; const QString &getName() const;
virtual const QString &getDisplayName() const;
bool isTwitchChannel() const; bool isTwitchChannel() const;
virtual bool isEmpty() const; virtual bool isEmpty() const;
LimitedQueueSnapshot<MessagePtr> getMessageSnapshot(); LimitedQueueSnapshot<MessagePtr> getMessageSnapshot();

View file

@ -0,0 +1,56 @@
#include "ChatroomChannel.hpp"
#include <QDebug>
#include "TwitchApi.hpp"
#include "common/Common.hpp"
#include "messages/Emote.hpp"
#include "providers/bttv/BttvEmotes.hpp"
#include "providers/bttv/LoadBttvChannelEmote.hpp"
#include "singletons/Emotes.hpp"
namespace chatterino {
ChatroomChannel::ChatroomChannel(const QString &channelName,
TwitchBadges &globalTwitchBadges,
BttvEmotes &globalBttv, FfzEmotes &globalFfz)
: TwitchChannel(channelName, globalTwitchBadges, globalBttv, globalFfz)
{
auto listRef = channelName.splitRef(":");
if (listRef.size() > 2)
{
this->chatroomOwnerId = listRef[1].toString();
}
}
void ChatroomChannel::refreshChannelEmotes()
{
if (this->chatroomOwnerId.isEmpty())
{
return;
}
TwitchApi::findUserName(
this->chatroomOwnerId,
[this, weak = weakOf<Channel>(this)](QString username) {
BttvEmotes::loadChannel(username, [this, weak](auto &&emoteMap) {
if (auto shared = weak.lock())
this->bttvEmotes_.set(
std::make_shared<EmoteMap>(std::move(emoteMap)));
});
FfzEmotes::loadChannel(username, [this, weak](auto &&emoteMap) {
if (auto shared = weak.lock())
this->ffzEmotes_.set(
std::make_shared<EmoteMap>(std::move(emoteMap)));
});
if (auto shared = weak.lock())
{
this->chatroomOwnerName = username;
}
});
}
const QString &ChatroomChannel::getDisplayName() const
{
return this->chatroomOwnerName;
}
} // namespace chatterino

View file

@ -0,0 +1,27 @@
#pragma once
#include "TwitchChannel.hpp"
#include <QString>
#include <atomic>
namespace chatterino {
class ChatroomChannel : public TwitchChannel
{
protected:
explicit ChatroomChannel(const QString &channelName,
TwitchBadges &globalTwitchBadges,
BttvEmotes &globalBttv, FfzEmotes &globalFfz);
virtual void refreshChannelEmotes() override;
virtual const QString &getDisplayName() const override;
QString chatroomOwnerId;
QString chatroomOwnerName;
friend class TwitchServer;
friend class TwitchMessageBuilder;
friend class IrcMessageHandler;
};
} // namespace chatterino

View file

@ -57,4 +57,29 @@ void TwitchApi::findUserId(const QString user,
request.execute(); request.execute();
} }
void TwitchApi::findUserName(const QString userid,
std::function<void(QString)> successCallback)
{
QString requestUrl("https://api.twitch.tv/kraken/users/" + userid);
NetworkRequest request(requestUrl);
request.setCaller(QThread::currentThread());
request.makeAuthorizedV5(getDefaultClientID());
request.setTimeout(30000);
request.onSuccess([successCallback](auto result) mutable -> Outcome {
auto root = result.parseJson();
auto name = root.value("name");
if (!name.isString())
{
log("API Error: while getting user name, `name` is not a string");
successCallback("");
return Failure;
}
successCallback(name.toString());
return Success;
});
request.execute();
}
} // namespace chatterino } // namespace chatterino

View file

@ -10,6 +10,8 @@ class TwitchApi
public: public:
static void findUserId(const QString user, static void findUserId(const QString user,
std::function<void(QString)> callback); std::function<void(QString)> callback);
static void findUserName(const QString userid,
std::function<void(QString)> callback);
private: private:
}; };

View file

@ -438,7 +438,8 @@ void TwitchChannel::setLive(bool newLiveStatus)
getApp()->windows->sendAlert(); getApp()->windows->sendAlert();
} }
} }
auto live = makeSystemMessage(this->getName() + " is live"); auto live =
makeSystemMessage(this->getDisplayName() + " is live");
this->addMessage(live); this->addMessage(live);
} }
else else

View file

@ -32,7 +32,7 @@ class BttvEmotes;
class TwitchServer; class TwitchServer;
class TwitchChannel final : public Channel, pajlada::Signals::SignalHolder class TwitchChannel : public Channel, pajlada::Signals::SignalHolder
{ {
public: public:
struct StreamStatus { struct StreamStatus {
@ -82,7 +82,7 @@ public:
std::shared_ptr<const EmoteMap> bttvEmotes() const; std::shared_ptr<const EmoteMap> bttvEmotes() const;
std::shared_ptr<const EmoteMap> ffzEmotes() const; std::shared_ptr<const EmoteMap> ffzEmotes() const;
void refreshChannelEmotes(); virtual void refreshChannelEmotes();
// Badges // Badges
boost::optional<EmotePtr> ffzCustomModBadge() const; boost::optional<EmotePtr> ffzCustomModBadge() const;
@ -104,10 +104,12 @@ private:
QString localizedName; QString localizedName;
}; };
protected:
explicit TwitchChannel(const QString &channelName, explicit TwitchChannel(const QString &channelName,
TwitchBadges &globalTwitchBadges, TwitchBadges &globalTwitchBadges,
BttvEmotes &globalBttv, FfzEmotes &globalFfz); BttvEmotes &globalBttv, FfzEmotes &globalFfz);
private:
// Methods // Methods
void refreshLiveStatus(); void refreshLiveStatus();
Outcome parseLiveStatus(const rapidjson::Document &document); Outcome parseLiveStatus(const rapidjson::Document &document);
@ -134,11 +136,14 @@ private:
// Emotes // Emotes
TwitchBadges &globalTwitchBadges_; TwitchBadges &globalTwitchBadges_;
protected:
BttvEmotes &globalBttv_; BttvEmotes &globalBttv_;
FfzEmotes &globalFfz_; FfzEmotes &globalFfz_;
Atomic<std::shared_ptr<const EmoteMap>> bttvEmotes_; Atomic<std::shared_ptr<const EmoteMap>> bttvEmotes_;
Atomic<std::shared_ptr<const EmoteMap>> ffzEmotes_; Atomic<std::shared_ptr<const EmoteMap>> ffzEmotes_;
private:
// Badges // Badges
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": ...

View file

@ -6,6 +6,7 @@
#include "controllers/highlights/HighlightController.hpp" #include "controllers/highlights/HighlightController.hpp"
#include "messages/Message.hpp" #include "messages/Message.hpp"
#include "messages/MessageBuilder.hpp" #include "messages/MessageBuilder.hpp"
#include "providers/twitch/ChatroomChannel.hpp"
#include "providers/twitch/IrcMessageHandler.hpp" #include "providers/twitch/IrcMessageHandler.hpp"
#include "providers/twitch/PubsubClient.hpp" #include "providers/twitch/PubsubClient.hpp"
#include "providers/twitch/TwitchAccount.hpp" #include "providers/twitch/TwitchAccount.hpp"
@ -22,6 +23,21 @@ using namespace std::chrono_literals;
namespace chatterino { namespace chatterino {
namespace {
bool isChatroom(const QString &channel)
{
if (channel.left(10) == "chatrooms:")
{
auto reflist = channel.splitRef(':');
if (reflist.size() == 3)
{
return true;
}
}
return false;
}
} // namespace
TwitchServer::TwitchServer() TwitchServer::TwitchServer()
: whispersChannel(new Channel("/whispers", Channel::Type::TwitchWhispers)) : whispersChannel(new Channel("/whispers", Channel::Type::TwitchWhispers))
, mentionsChannel(new Channel("/mentions", Channel::Type::TwitchMentions)) , mentionsChannel(new Channel("/mentions", Channel::Type::TwitchMentions))
@ -92,8 +108,18 @@ void TwitchServer::initializeConnection(IrcConnection *connection, bool isRead,
std::shared_ptr<Channel> TwitchServer::createChannel(const QString &channelName) std::shared_ptr<Channel> TwitchServer::createChannel(const QString &channelName)
{ {
auto channel = std::shared_ptr<TwitchChannel>(new TwitchChannel( std::shared_ptr<TwitchChannel> channel;
if (isChatroom(channelName))
{
channel = std::static_pointer_cast<TwitchChannel>(
std::shared_ptr<ChatroomChannel>(new ChatroomChannel(
channelName, this->twitchBadges, this->bttv, this->ffz)));
}
else
{
channel = std::shared_ptr<TwitchChannel>(new TwitchChannel(
channelName, this->twitchBadges, this->bttv, this->ffz)); channelName, this->twitchBadges, this->bttv, this->ffz));
}
channel->initialize(); channel->initialize();
channel->sendMessageSignal.connect( channel->sendMessageSignal.connect(