mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
chore: refactor TwitchIrcServer (#5421)
This commit is contained in:
parent
2a46ee708e
commit
b6dc5d9e03
|
@ -19,6 +19,7 @@
|
||||||
- Dev: Add doxygen build target. (#5377)
|
- Dev: Add doxygen build target. (#5377)
|
||||||
- Dev: Make printing of strings in tests easier. (#5379)
|
- Dev: Make printing of strings in tests easier. (#5379)
|
||||||
- Dev: Refactor and document `Scrollbar`. (#5334, #5393)
|
- Dev: Refactor and document `Scrollbar`. (#5334, #5393)
|
||||||
|
- Dev: Refactor `TwitchIrcServer`, making it abstracted. (#5421)
|
||||||
- Dev: Reduced the amount of scale events. (#5404, #5406)
|
- Dev: Reduced the amount of scale events. (#5404, #5406)
|
||||||
- Dev: Removed unused timegate settings. (#5361)
|
- Dev: Removed unused timegate settings. (#5361)
|
||||||
- Dev: All Lua globals now show in the `c2` global in the LuaLS metadata. (#5385)
|
- Dev: All Lua globals now show in the `c2` global in the LuaLS metadata. (#5385)
|
||||||
|
|
|
@ -118,6 +118,13 @@ public:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IAbstractIrcServer *getTwitchAbstract() override
|
||||||
|
{
|
||||||
|
assert(false && "EmptyApplication::getTwitchAbstract was called "
|
||||||
|
"without being initialized");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
PubSub *getTwitchPubSub() override
|
PubSub *getTwitchPubSub() override
|
||||||
{
|
{
|
||||||
assert(false && "getTwitchPubSub was called without being initialized");
|
assert(false && "getTwitchPubSub was called without being initialized");
|
||||||
|
|
|
@ -2,8 +2,13 @@
|
||||||
|
|
||||||
#include "mocks/Channel.hpp"
|
#include "mocks/Channel.hpp"
|
||||||
#include "providers/bttv/BttvEmotes.hpp"
|
#include "providers/bttv/BttvEmotes.hpp"
|
||||||
|
#include "providers/bttv/BttvLiveUpdates.hpp"
|
||||||
#include "providers/ffz/FfzEmotes.hpp"
|
#include "providers/ffz/FfzEmotes.hpp"
|
||||||
|
#include "providers/seventv/eventapi/Client.hpp"
|
||||||
|
#include "providers/seventv/eventapi/Dispatch.hpp"
|
||||||
|
#include "providers/seventv/eventapi/Message.hpp"
|
||||||
#include "providers/seventv/SeventvEmotes.hpp"
|
#include "providers/seventv/SeventvEmotes.hpp"
|
||||||
|
#include "providers/seventv/SeventvEventAPI.hpp"
|
||||||
#include "providers/twitch/TwitchIrcServer.hpp"
|
#include "providers/twitch/TwitchIrcServer.hpp"
|
||||||
|
|
||||||
namespace chatterino::mock {
|
namespace chatterino::mock {
|
||||||
|
@ -16,22 +21,91 @@ public:
|
||||||
std::shared_ptr<Channel>(new MockChannel("testaccount_420")))
|
std::shared_ptr<Channel>(new MockChannel("testaccount_420")))
|
||||||
, watchingChannel(this->watchingChannelInner,
|
, watchingChannel(this->watchingChannelInner,
|
||||||
Channel::Type::TwitchWatching)
|
Channel::Type::TwitchWatching)
|
||||||
|
, whispersChannel(std::shared_ptr<Channel>(new MockChannel("whispers")))
|
||||||
|
, mentionsChannel(std::shared_ptr<Channel>(new MockChannel("forsen3")))
|
||||||
|
, liveChannel(std::shared_ptr<Channel>(new MockChannel("forsen")))
|
||||||
|
, automodChannel(std::shared_ptr<Channel>(new MockChannel("forsen2")))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void forEachChannelAndSpecialChannels(
|
||||||
|
std::function<void(ChannelPtr)> func) override
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Channel> getChannelOrEmptyByID(
|
||||||
|
const QString &channelID) override
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void dropSeventvChannel(const QString &userID,
|
||||||
|
const QString &emoteSetID) override
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<BttvLiveUpdates> &getBTTVLiveUpdates() override
|
||||||
|
{
|
||||||
|
return this->bttvLiveUpdates;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<SeventvEventAPI> &getSeventvEventAPI() override
|
||||||
|
{
|
||||||
|
return this->seventvEventAPI;
|
||||||
|
}
|
||||||
|
|
||||||
const IndirectChannel &getWatchingChannel() const override
|
const IndirectChannel &getWatchingChannel() const override
|
||||||
{
|
{
|
||||||
return this->watchingChannel;
|
return this->watchingChannel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setWatchingChannel(ChannelPtr newWatchingChannel) override
|
||||||
|
{
|
||||||
|
this->watchingChannel.reset(newWatchingChannel);
|
||||||
|
}
|
||||||
|
|
||||||
QString getLastUserThatWhisperedMe() const override
|
QString getLastUserThatWhisperedMe() const override
|
||||||
{
|
{
|
||||||
return this->lastUserThatWhisperedMe;
|
return this->lastUserThatWhisperedMe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setLastUserThatWhisperedMe(const QString &user) override
|
||||||
|
{
|
||||||
|
this->lastUserThatWhisperedMe = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChannelPtr getWhispersChannel() const override
|
||||||
|
{
|
||||||
|
return this->whispersChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChannelPtr getMentionsChannel() const override
|
||||||
|
{
|
||||||
|
return this->mentionsChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChannelPtr getLiveChannel() const override
|
||||||
|
{
|
||||||
|
return this->liveChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChannelPtr getAutomodChannel() const override
|
||||||
|
{
|
||||||
|
return this->automodChannel;
|
||||||
|
}
|
||||||
|
|
||||||
ChannelPtr watchingChannelInner;
|
ChannelPtr watchingChannelInner;
|
||||||
IndirectChannel watchingChannel;
|
IndirectChannel watchingChannel;
|
||||||
|
ChannelPtr whispersChannel;
|
||||||
|
ChannelPtr mentionsChannel;
|
||||||
|
ChannelPtr liveChannel;
|
||||||
|
ChannelPtr automodChannel;
|
||||||
QString lastUserThatWhisperedMe{"forsen"};
|
QString lastUserThatWhisperedMe{"forsen"};
|
||||||
|
|
||||||
|
std::unique_ptr<BttvLiveUpdates> bttvLiveUpdates;
|
||||||
|
std::unique_ptr<SeventvEventAPI> seventvEventAPI;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace chatterino::mock
|
} // namespace chatterino::mock
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "controllers/sound/ISoundController.hpp"
|
#include "controllers/sound/ISoundController.hpp"
|
||||||
#include "providers/bttv/BttvEmotes.hpp"
|
#include "providers/bttv/BttvEmotes.hpp"
|
||||||
#include "providers/ffz/FfzEmotes.hpp"
|
#include "providers/ffz/FfzEmotes.hpp"
|
||||||
|
#include "providers/irc/AbstractIrcServer.hpp"
|
||||||
#include "providers/links/LinkResolver.hpp"
|
#include "providers/links/LinkResolver.hpp"
|
||||||
#include "providers/seventv/SeventvAPI.hpp"
|
#include "providers/seventv/SeventvAPI.hpp"
|
||||||
#include "providers/seventv/SeventvEmotes.hpp"
|
#include "providers/seventv/SeventvEmotes.hpp"
|
||||||
|
@ -131,7 +132,7 @@ Application::Application(Settings &_settings, const Paths &paths,
|
||||||
, commands(&this->emplace<CommandController>())
|
, commands(&this->emplace<CommandController>())
|
||||||
, notifications(&this->emplace<NotificationController>())
|
, notifications(&this->emplace<NotificationController>())
|
||||||
, highlights(&this->emplace<HighlightController>())
|
, highlights(&this->emplace<HighlightController>())
|
||||||
, twitch(&this->emplace<TwitchIrcServer>())
|
, twitch(new TwitchIrcServer)
|
||||||
, ffzBadges(&this->emplace<FfzBadges>())
|
, ffzBadges(&this->emplace<FfzBadges>())
|
||||||
, seventvBadges(&this->emplace<SeventvBadges>())
|
, seventvBadges(&this->emplace<SeventvBadges>())
|
||||||
, userData(&this->emplace(new UserDataController(paths)))
|
, userData(&this->emplace(new UserDataController(paths)))
|
||||||
|
@ -170,6 +171,7 @@ void Application::fakeDtor()
|
||||||
this->bttvEmotes.reset();
|
this->bttvEmotes.reset();
|
||||||
this->ffzEmotes.reset();
|
this->ffzEmotes.reset();
|
||||||
this->seventvEmotes.reset();
|
this->seventvEmotes.reset();
|
||||||
|
// this->twitch.reset();
|
||||||
this->fonts.reset();
|
this->fonts.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,7 +485,14 @@ ITwitchIrcServer *Application::getTwitch()
|
||||||
{
|
{
|
||||||
assertInGuiThread();
|
assertInGuiThread();
|
||||||
|
|
||||||
return this->twitch;
|
return this->twitch.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
IAbstractIrcServer *Application::getTwitchAbstract()
|
||||||
|
{
|
||||||
|
assertInGuiThread();
|
||||||
|
|
||||||
|
return this->twitch.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
PubSub *Application::getTwitchPubSub()
|
PubSub *Application::getTwitchPubSub()
|
||||||
|
@ -865,17 +874,25 @@ void Application::initPubSub()
|
||||||
chan->addMessage(p.first);
|
chan->addMessage(p.first);
|
||||||
chan->addMessage(p.second);
|
chan->addMessage(p.second);
|
||||||
|
|
||||||
getApp()->twitch->automodChannel->addMessage(
|
getIApp()
|
||||||
p.first);
|
->getTwitch()
|
||||||
getApp()->twitch->automodChannel->addMessage(
|
->getAutomodChannel()
|
||||||
p.second);
|
->addMessage(p.first);
|
||||||
|
getIApp()
|
||||||
|
->getTwitch()
|
||||||
|
->getAutomodChannel()
|
||||||
|
->addMessage(p.second);
|
||||||
|
|
||||||
if (getSettings()->showAutomodInMentions)
|
if (getSettings()->showAutomodInMentions)
|
||||||
{
|
{
|
||||||
getApp()->twitch->mentionsChannel->addMessage(
|
getIApp()
|
||||||
p.first);
|
->getTwitch()
|
||||||
getApp()->twitch->mentionsChannel->addMessage(
|
->getMentionsChannel()
|
||||||
p.second);
|
->addMessage(p.first);
|
||||||
|
getIApp()
|
||||||
|
->getTwitch()
|
||||||
|
->getMentionsChannel()
|
||||||
|
->addMessage(p.second);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -984,7 +1001,9 @@ void Application::initPubSub()
|
||||||
|
|
||||||
void Application::initBttvLiveUpdates()
|
void Application::initBttvLiveUpdates()
|
||||||
{
|
{
|
||||||
if (!this->twitch->bttvLiveUpdates)
|
auto &bttvLiveUpdates = this->twitch->getBTTVLiveUpdates();
|
||||||
|
|
||||||
|
if (!bttvLiveUpdates)
|
||||||
{
|
{
|
||||||
qCDebug(chatterinoBttv)
|
qCDebug(chatterinoBttv)
|
||||||
<< "Skipping initialization of Live Updates as it's disabled";
|
<< "Skipping initialization of Live Updates as it's disabled";
|
||||||
|
@ -993,8 +1012,8 @@ void Application::initBttvLiveUpdates()
|
||||||
|
|
||||||
// We can safely ignore these signal connections since the twitch object will always
|
// We can safely ignore these signal connections since the twitch object will always
|
||||||
// be destroyed before the Application
|
// be destroyed before the Application
|
||||||
std::ignore = this->twitch->bttvLiveUpdates->signals_.emoteAdded.connect(
|
std::ignore =
|
||||||
[&](const auto &data) {
|
bttvLiveUpdates->signals_.emoteAdded.connect([&](const auto &data) {
|
||||||
auto chan = this->twitch->getChannelOrEmptyByID(data.channelID);
|
auto chan = this->twitch->getChannelOrEmptyByID(data.channelID);
|
||||||
|
|
||||||
postToThread([chan, data] {
|
postToThread([chan, data] {
|
||||||
|
@ -1004,8 +1023,8 @@ void Application::initBttvLiveUpdates()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
std::ignore = this->twitch->bttvLiveUpdates->signals_.emoteUpdated.connect(
|
std::ignore =
|
||||||
[&](const auto &data) {
|
bttvLiveUpdates->signals_.emoteUpdated.connect([&](const auto &data) {
|
||||||
auto chan = this->twitch->getChannelOrEmptyByID(data.channelID);
|
auto chan = this->twitch->getChannelOrEmptyByID(data.channelID);
|
||||||
|
|
||||||
postToThread([chan, data] {
|
postToThread([chan, data] {
|
||||||
|
@ -1015,8 +1034,8 @@ void Application::initBttvLiveUpdates()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
std::ignore = this->twitch->bttvLiveUpdates->signals_.emoteRemoved.connect(
|
std::ignore =
|
||||||
[&](const auto &data) {
|
bttvLiveUpdates->signals_.emoteRemoved.connect([&](const auto &data) {
|
||||||
auto chan = this->twitch->getChannelOrEmptyByID(data.channelID);
|
auto chan = this->twitch->getChannelOrEmptyByID(data.channelID);
|
||||||
|
|
||||||
postToThread([chan, data] {
|
postToThread([chan, data] {
|
||||||
|
@ -1026,12 +1045,14 @@ void Application::initBttvLiveUpdates()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
this->twitch->bttvLiveUpdates->start();
|
bttvLiveUpdates->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::initSeventvEventAPI()
|
void Application::initSeventvEventAPI()
|
||||||
{
|
{
|
||||||
if (!this->twitch->seventvEventAPI)
|
auto &seventvEventAPI = this->twitch->getSeventvEventAPI();
|
||||||
|
|
||||||
|
if (!seventvEventAPI)
|
||||||
{
|
{
|
||||||
qCDebug(chatterinoSeventvEventAPI)
|
qCDebug(chatterinoSeventvEventAPI)
|
||||||
<< "Skipping initialization as the EventAPI is disabled";
|
<< "Skipping initialization as the EventAPI is disabled";
|
||||||
|
@ -1040,8 +1061,8 @@ void Application::initSeventvEventAPI()
|
||||||
|
|
||||||
// We can safely ignore these signal connections since the twitch object will always
|
// We can safely ignore these signal connections since the twitch object will always
|
||||||
// be destroyed before the Application
|
// be destroyed before the Application
|
||||||
std::ignore = this->twitch->seventvEventAPI->signals_.emoteAdded.connect(
|
std::ignore =
|
||||||
[&](const auto &data) {
|
seventvEventAPI->signals_.emoteAdded.connect([&](const auto &data) {
|
||||||
postToThread([this, data] {
|
postToThread([this, data] {
|
||||||
this->twitch->forEachSeventvEmoteSet(
|
this->twitch->forEachSeventvEmoteSet(
|
||||||
data.emoteSetID, [data](TwitchChannel &chan) {
|
data.emoteSetID, [data](TwitchChannel &chan) {
|
||||||
|
@ -1049,8 +1070,8 @@ void Application::initSeventvEventAPI()
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
std::ignore = this->twitch->seventvEventAPI->signals_.emoteUpdated.connect(
|
std::ignore =
|
||||||
[&](const auto &data) {
|
seventvEventAPI->signals_.emoteUpdated.connect([&](const auto &data) {
|
||||||
postToThread([this, data] {
|
postToThread([this, data] {
|
||||||
this->twitch->forEachSeventvEmoteSet(
|
this->twitch->forEachSeventvEmoteSet(
|
||||||
data.emoteSetID, [data](TwitchChannel &chan) {
|
data.emoteSetID, [data](TwitchChannel &chan) {
|
||||||
|
@ -1058,8 +1079,8 @@ void Application::initSeventvEventAPI()
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
std::ignore = this->twitch->seventvEventAPI->signals_.emoteRemoved.connect(
|
std::ignore =
|
||||||
[&](const auto &data) {
|
seventvEventAPI->signals_.emoteRemoved.connect([&](const auto &data) {
|
||||||
postToThread([this, data] {
|
postToThread([this, data] {
|
||||||
this->twitch->forEachSeventvEmoteSet(
|
this->twitch->forEachSeventvEmoteSet(
|
||||||
data.emoteSetID, [data](TwitchChannel &chan) {
|
data.emoteSetID, [data](TwitchChannel &chan) {
|
||||||
|
@ -1067,15 +1088,15 @@ void Application::initSeventvEventAPI()
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
std::ignore = this->twitch->seventvEventAPI->signals_.userUpdated.connect(
|
std::ignore =
|
||||||
[&](const auto &data) {
|
seventvEventAPI->signals_.userUpdated.connect([&](const auto &data) {
|
||||||
this->twitch->forEachSeventvUser(data.userID,
|
this->twitch->forEachSeventvUser(data.userID,
|
||||||
[data](TwitchChannel &chan) {
|
[data](TwitchChannel &chan) {
|
||||||
chan.updateSeventvUser(data);
|
chan.updateSeventvUser(data);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
this->twitch->seventvEventAPI->start();
|
seventvEventAPI->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
Application *getApp()
|
Application *getApp()
|
||||||
|
|
|
@ -54,6 +54,7 @@ class FfzEmotes;
|
||||||
class SeventvEmotes;
|
class SeventvEmotes;
|
||||||
class ILinkResolver;
|
class ILinkResolver;
|
||||||
class IStreamerMode;
|
class IStreamerMode;
|
||||||
|
class IAbstractIrcServer;
|
||||||
|
|
||||||
class IApplication
|
class IApplication
|
||||||
{
|
{
|
||||||
|
@ -77,6 +78,7 @@ public:
|
||||||
virtual HighlightController *getHighlights() = 0;
|
virtual HighlightController *getHighlights() = 0;
|
||||||
virtual NotificationController *getNotifications() = 0;
|
virtual NotificationController *getNotifications() = 0;
|
||||||
virtual ITwitchIrcServer *getTwitch() = 0;
|
virtual ITwitchIrcServer *getTwitch() = 0;
|
||||||
|
virtual IAbstractIrcServer *getTwitchAbstract() = 0;
|
||||||
virtual PubSub *getTwitchPubSub() = 0;
|
virtual PubSub *getTwitchPubSub() = 0;
|
||||||
virtual Logging *getChatLogger() = 0;
|
virtual Logging *getChatLogger() = 0;
|
||||||
virtual IChatterinoBadges *getChatterinoBadges() = 0;
|
virtual IChatterinoBadges *getChatterinoBadges() = 0;
|
||||||
|
@ -147,11 +149,7 @@ private:
|
||||||
CommandController *const commands{};
|
CommandController *const commands{};
|
||||||
NotificationController *const notifications{};
|
NotificationController *const notifications{};
|
||||||
HighlightController *const highlights{};
|
HighlightController *const highlights{};
|
||||||
|
std::unique_ptr<TwitchIrcServer> twitch;
|
||||||
public:
|
|
||||||
TwitchIrcServer *const twitch{};
|
|
||||||
|
|
||||||
private:
|
|
||||||
FfzBadges *const ffzBadges{};
|
FfzBadges *const ffzBadges{};
|
||||||
SeventvBadges *const seventvBadges{};
|
SeventvBadges *const seventvBadges{};
|
||||||
UserDataController *const userData{};
|
UserDataController *const userData{};
|
||||||
|
@ -191,6 +189,7 @@ public:
|
||||||
NotificationController *getNotifications() override;
|
NotificationController *getNotifications() override;
|
||||||
HighlightController *getHighlights() override;
|
HighlightController *getHighlights() override;
|
||||||
ITwitchIrcServer *getTwitch() override;
|
ITwitchIrcServer *getTwitch() override;
|
||||||
|
IAbstractIrcServer *getTwitchAbstract() override;
|
||||||
PubSub *getTwitchPubSub() override;
|
PubSub *getTwitchPubSub() override;
|
||||||
Logging *getChatLogger() override;
|
Logging *getChatLogger() override;
|
||||||
FfzBadges *getFfzBadges() override;
|
FfzBadges *getFfzBadges() override;
|
||||||
|
|
|
@ -390,9 +390,9 @@ QString popup(const CommandContext &ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open channel passed as argument in a popup
|
// Open channel passed as argument in a popup
|
||||||
auto *app = getApp();
|
auto targetChannel =
|
||||||
auto targetChannel = app->twitch->getOrAddChannel(target);
|
getIApp()->getTwitchAbstract()->getOrAddChannel(target);
|
||||||
app->getWindows()->openInPopup(targetChannel);
|
getIApp()->getWindows()->openInPopup(targetChannel);
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -533,7 +533,8 @@ QString sendRawMessage(const CommandContext &ctx)
|
||||||
|
|
||||||
if (ctx.channel->isTwitchChannel())
|
if (ctx.channel->isTwitchChannel())
|
||||||
{
|
{
|
||||||
getApp()->twitch->sendRawMessage(ctx.words.mid(1).join(" "));
|
getIApp()->getTwitchAbstract()->sendRawMessage(
|
||||||
|
ctx.words.mid(1).join(" "));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -566,7 +567,7 @@ QString injectFakeMessage(const CommandContext &ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ircText = ctx.words.mid(1).join(" ");
|
auto ircText = ctx.words.mid(1).join(" ");
|
||||||
getApp()->twitch->addFakeMessage(ircText);
|
getIApp()->getTwitchAbstract()->addFakeMessage(ircText);
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -667,7 +668,7 @@ QString openUsercard(const CommandContext &ctx)
|
||||||
stripChannelName(channelName);
|
stripChannelName(channelName);
|
||||||
|
|
||||||
ChannelPtr channelTemp =
|
ChannelPtr channelTemp =
|
||||||
getApp()->twitch->getChannelOrEmpty(channelName);
|
getIApp()->getTwitchAbstract()->getChannelOrEmpty(channelName);
|
||||||
|
|
||||||
if (channelTemp->isEmpty())
|
if (channelTemp->isEmpty())
|
||||||
{
|
{
|
||||||
|
|
|
@ -92,7 +92,7 @@ QString formatWhisperError(HelixWhisperError error, const QString &message)
|
||||||
|
|
||||||
bool appendWhisperMessageWordsLocally(const QStringList &words)
|
bool appendWhisperMessageWordsLocally(const QStringList &words)
|
||||||
{
|
{
|
||||||
auto *app = getApp();
|
auto *app = getIApp();
|
||||||
|
|
||||||
MessageBuilder b;
|
MessageBuilder b;
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ bool appendWhisperMessageWordsLocally(const QStringList &words)
|
||||||
b->flags.set(MessageFlag::Whisper);
|
b->flags.set(MessageFlag::Whisper);
|
||||||
auto messagexD = b.release();
|
auto messagexD = b.release();
|
||||||
|
|
||||||
app->twitch->whispersChannel->addMessage(messagexD);
|
getIApp()->getTwitch()->getWhispersChannel()->addMessage(messagexD);
|
||||||
|
|
||||||
auto overrideFlags = std::optional<MessageFlags>(messagexD->flags);
|
auto overrideFlags = std::optional<MessageFlags>(messagexD->flags);
|
||||||
overrideFlags->set(MessageFlag::DoNotLog);
|
overrideFlags->set(MessageFlag::DoNotLog);
|
||||||
|
@ -186,7 +186,7 @@ bool appendWhisperMessageWordsLocally(const QStringList &words)
|
||||||
!(getSettings()->streamerModeSuppressInlineWhispers &&
|
!(getSettings()->streamerModeSuppressInlineWhispers &&
|
||||||
getIApp()->getStreamerMode()->isEnabled()))
|
getIApp()->getStreamerMode()->isEnabled()))
|
||||||
{
|
{
|
||||||
app->twitch->forEachChannel(
|
app->getTwitchAbstract()->forEachChannel(
|
||||||
[&messagexD, overrideFlags](ChannelPtr _channel) {
|
[&messagexD, overrideFlags](ChannelPtr _channel) {
|
||||||
_channel->addMessage(messagexD, overrideFlags);
|
_channel->addMessage(messagexD, overrideFlags);
|
||||||
});
|
});
|
||||||
|
|
|
@ -124,7 +124,7 @@ void NotificationController::fetchFakeChannels()
|
||||||
for (std::vector<int>::size_type i = 0;
|
for (std::vector<int>::size_type i = 0;
|
||||||
i < channelMap[Platform::Twitch].raw().size(); i++)
|
i < channelMap[Platform::Twitch].raw().size(); i++)
|
||||||
{
|
{
|
||||||
auto chan = getApp()->twitch->getChannelOrEmpty(
|
auto chan = getIApp()->getTwitchAbstract()->getChannelOrEmpty(
|
||||||
channelMap[Platform::Twitch].raw()[i]);
|
channelMap[Platform::Twitch].raw()[i]);
|
||||||
if (chan->isEmpty())
|
if (chan->isEmpty())
|
||||||
{
|
{
|
||||||
|
@ -202,7 +202,7 @@ void NotificationController::checkStream(bool live, QString channelName)
|
||||||
}
|
}
|
||||||
MessageBuilder builder;
|
MessageBuilder builder;
|
||||||
TwitchMessageBuilder::liveMessage(channelName, &builder);
|
TwitchMessageBuilder::liveMessage(channelName, &builder);
|
||||||
getApp()->twitch->liveChannel->addMessage(builder.release());
|
getIApp()->getTwitch()->getLiveChannel()->addMessage(builder.release());
|
||||||
|
|
||||||
// Indicate that we have pushed notifications for this stream
|
// Indicate that we have pushed notifications for this stream
|
||||||
fakeTwitchChannels.push_back(channelName);
|
fakeTwitchChannels.push_back(channelName);
|
||||||
|
@ -217,7 +217,7 @@ void NotificationController::removeFakeChannel(const QString channelName)
|
||||||
fakeTwitchChannels.erase(it);
|
fakeTwitchChannels.erase(it);
|
||||||
// "delete" old 'CHANNEL is live' message
|
// "delete" old 'CHANNEL is live' message
|
||||||
LimitedQueueSnapshot<MessagePtr> snapshot =
|
LimitedQueueSnapshot<MessagePtr> snapshot =
|
||||||
getApp()->twitch->liveChannel->getMessageSnapshot();
|
getIApp()->getTwitch()->getLiveChannel()->getMessageSnapshot();
|
||||||
int snapshotLength = snapshot.size();
|
int snapshotLength = snapshot.size();
|
||||||
|
|
||||||
// MSVC hates this code if the parens are not there
|
// MSVC hates this code if the parens are not there
|
||||||
|
|
|
@ -300,7 +300,7 @@ int ChannelRef::get_by_name(lua_State *L)
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
auto chn = getApp()->twitch->getChannelOrEmpty(name);
|
auto chn = getIApp()->getTwitchAbstract()->getChannelOrEmpty(name);
|
||||||
lua::push(L, chn);
|
lua::push(L, chn);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -324,7 +324,7 @@ int ChannelRef::get_by_twitch_id(lua_State *L)
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
auto chn = getApp()->twitch->getChannelOrEmptyByID(id);
|
auto chn = getIApp()->getTwitch()->getChannelOrEmptyByID(id);
|
||||||
|
|
||||||
lua::push(L, chn);
|
lua::push(L, chn);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -17,7 +17,24 @@ class Channel;
|
||||||
using ChannelPtr = std::shared_ptr<Channel>;
|
using ChannelPtr = std::shared_ptr<Channel>;
|
||||||
class RatelimitBucket;
|
class RatelimitBucket;
|
||||||
|
|
||||||
class AbstractIrcServer : public QObject
|
class IAbstractIrcServer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void connect() = 0;
|
||||||
|
|
||||||
|
virtual void sendRawMessage(const QString &rawMessage) = 0;
|
||||||
|
|
||||||
|
virtual ChannelPtr getOrAddChannel(const QString &dirtyChannelName) = 0;
|
||||||
|
virtual ChannelPtr getChannelOrEmpty(const QString &dirtyChannelName) = 0;
|
||||||
|
|
||||||
|
virtual void addFakeMessage(const QString &data) = 0;
|
||||||
|
|
||||||
|
virtual void addGlobalSystemMessage(const QString &messageText) = 0;
|
||||||
|
|
||||||
|
virtual void forEachChannel(std::function<void(ChannelPtr)> func) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AbstractIrcServer : public IAbstractIrcServer, public QObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum ConnectionType { Read = 1, Write = 2, Both = 3 };
|
enum ConnectionType { Read = 1, Write = 2, Both = 3 };
|
||||||
|
@ -33,27 +50,27 @@ public:
|
||||||
void initializeIrc();
|
void initializeIrc();
|
||||||
|
|
||||||
// connection
|
// connection
|
||||||
void connect();
|
void connect() final;
|
||||||
void disconnect();
|
void disconnect();
|
||||||
|
|
||||||
void sendMessage(const QString &channelName, const QString &message);
|
void sendMessage(const QString &channelName, const QString &message);
|
||||||
virtual void sendRawMessage(const QString &rawMessage);
|
void sendRawMessage(const QString &rawMessage) override;
|
||||||
|
|
||||||
// channels
|
// channels
|
||||||
ChannelPtr getOrAddChannel(const QString &dirtyChannelName);
|
ChannelPtr getOrAddChannel(const QString &dirtyChannelName) final;
|
||||||
ChannelPtr getChannelOrEmpty(const QString &dirtyChannelName);
|
ChannelPtr getChannelOrEmpty(const QString &dirtyChannelName) final;
|
||||||
std::vector<std::weak_ptr<Channel>> getChannels();
|
std::vector<std::weak_ptr<Channel>> getChannels();
|
||||||
|
|
||||||
// signals
|
// signals
|
||||||
pajlada::Signals::NoArgSignal connected;
|
pajlada::Signals::NoArgSignal connected;
|
||||||
pajlada::Signals::NoArgSignal disconnected;
|
pajlada::Signals::NoArgSignal disconnected;
|
||||||
|
|
||||||
void addFakeMessage(const QString &data);
|
void addFakeMessage(const QString &data) final;
|
||||||
|
|
||||||
void addGlobalSystemMessage(const QString &messageText);
|
void addGlobalSystemMessage(const QString &messageText) final;
|
||||||
|
|
||||||
// iteration
|
// iteration
|
||||||
void forEachChannel(std::function<void(ChannelPtr)> func);
|
void forEachChannel(std::function<void(ChannelPtr)> func) final;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
AbstractIrcServer();
|
AbstractIrcServer();
|
||||||
|
|
|
@ -244,7 +244,7 @@ void IrcServer::privateMessageReceived(Communi::IrcPrivateMessage *message)
|
||||||
|
|
||||||
if (highlighted && showInMentions)
|
if (highlighted && showInMentions)
|
||||||
{
|
{
|
||||||
getApp()->twitch->mentionsChannel->addMessage(msg);
|
getIApp()->getTwitch()->getMentionsChannel()->addMessage(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "messages/MessageColor.hpp"
|
#include "messages/MessageColor.hpp"
|
||||||
#include "messages/MessageElement.hpp"
|
#include "messages/MessageElement.hpp"
|
||||||
#include "messages/MessageThread.hpp"
|
#include "messages/MessageThread.hpp"
|
||||||
|
#include "providers/irc/AbstractIrcServer.hpp"
|
||||||
#include "providers/twitch/ChannelPointReward.hpp"
|
#include "providers/twitch/ChannelPointReward.hpp"
|
||||||
#include "providers/twitch/TwitchAccount.hpp"
|
#include "providers/twitch/TwitchAccount.hpp"
|
||||||
#include "providers/twitch/TwitchAccountManager.hpp"
|
#include "providers/twitch/TwitchAccountManager.hpp"
|
||||||
|
@ -169,7 +170,7 @@ void updateReplyParticipatedStatus(const QVariantMap &tags,
|
||||||
}
|
}
|
||||||
|
|
||||||
ChannelPtr channelOrEmptyByTarget(const QString &target,
|
ChannelPtr channelOrEmptyByTarget(const QString &target,
|
||||||
TwitchIrcServer &server)
|
IAbstractIrcServer &server)
|
||||||
{
|
{
|
||||||
QString channelName;
|
QString channelName;
|
||||||
if (!trimChannelName(target, channelName))
|
if (!trimChannelName(target, channelName))
|
||||||
|
@ -677,9 +678,10 @@ std::vector<MessagePtr> IrcMessageHandler::parseMessageWithReply(
|
||||||
}
|
}
|
||||||
|
|
||||||
void IrcMessageHandler::handlePrivMessage(Communi::IrcPrivateMessage *message,
|
void IrcMessageHandler::handlePrivMessage(Communi::IrcPrivateMessage *message,
|
||||||
TwitchIrcServer &server)
|
ITwitchIrcServer &twitchServer,
|
||||||
|
IAbstractIrcServer &abstractIrcServer)
|
||||||
{
|
{
|
||||||
auto chan = channelOrEmptyByTarget(message->target(), server);
|
auto chan = channelOrEmptyByTarget(message->target(), abstractIrcServer);
|
||||||
if (chan->isEmpty())
|
if (chan->isEmpty())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -710,8 +712,8 @@ void IrcMessageHandler::handlePrivMessage(Communi::IrcPrivateMessage *message,
|
||||||
// https://mm2pl.github.io/emoji_rfc.pdf for more details
|
// https://mm2pl.github.io/emoji_rfc.pdf for more details
|
||||||
this->addMessage(
|
this->addMessage(
|
||||||
message, chan,
|
message, chan,
|
||||||
message->content().replace(COMBINED_FIXER, ZERO_WIDTH_JOINER), server,
|
message->content().replace(COMBINED_FIXER, ZERO_WIDTH_JOINER),
|
||||||
false, message->isAction());
|
twitchServer, false, message->isAction());
|
||||||
|
|
||||||
if (message->tags().contains(u"pinned-chat-paid-amount"_s))
|
if (message->tags().contains(u"pinned-chat-paid-amount"_s))
|
||||||
{
|
{
|
||||||
|
@ -733,7 +735,7 @@ void IrcMessageHandler::handleRoomStateMessage(Communi::IrcMessage *message)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto chan = getApp()->twitch->getChannelOrEmpty(chanName);
|
auto chan = getIApp()->getTwitchAbstract()->getChannelOrEmpty(chanName);
|
||||||
|
|
||||||
auto *twitchChannel = dynamic_cast<TwitchChannel *>(chan.get());
|
auto *twitchChannel = dynamic_cast<TwitchChannel *>(chan.get());
|
||||||
if (!twitchChannel)
|
if (!twitchChannel)
|
||||||
|
@ -795,7 +797,7 @@ void IrcMessageHandler::handleClearChatMessage(Communi::IrcMessage *message)
|
||||||
}
|
}
|
||||||
|
|
||||||
// get channel
|
// get channel
|
||||||
auto chan = getApp()->twitch->getChannelOrEmpty(chanName);
|
auto chan = getIApp()->getTwitchAbstract()->getChannelOrEmpty(chanName);
|
||||||
|
|
||||||
if (chan->isEmpty())
|
if (chan->isEmpty())
|
||||||
{
|
{
|
||||||
|
@ -839,7 +841,7 @@ void IrcMessageHandler::handleClearMessageMessage(Communi::IrcMessage *message)
|
||||||
}
|
}
|
||||||
|
|
||||||
// get channel
|
// get channel
|
||||||
auto chan = getApp()->twitch->getChannelOrEmpty(chanName);
|
auto chan = getIApp()->getTwitchAbstract()->getChannelOrEmpty(chanName);
|
||||||
|
|
||||||
if (chan->isEmpty())
|
if (chan->isEmpty())
|
||||||
{
|
{
|
||||||
|
@ -888,7 +890,7 @@ void IrcMessageHandler::handleUserStateMessage(Communi::IrcMessage *message)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto c = getApp()->twitch->getChannelOrEmpty(channelName);
|
auto c = getIApp()->getTwitchAbstract()->getChannelOrEmpty(channelName);
|
||||||
if (c->isEmpty())
|
if (c->isEmpty())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -943,7 +945,7 @@ void IrcMessageHandler::handleWhisperMessage(Communi::IrcMessage *ircMessage)
|
||||||
|
|
||||||
args.isReceivedWhisper = true;
|
args.isReceivedWhisper = true;
|
||||||
|
|
||||||
auto *c = getApp()->twitch->whispersChannel.get();
|
auto *c = getIApp()->getTwitch()->getWhispersChannel().get();
|
||||||
|
|
||||||
TwitchMessageBuilder builder(
|
TwitchMessageBuilder builder(
|
||||||
c, ircMessage, args,
|
c, ircMessage, args,
|
||||||
|
@ -959,11 +961,11 @@ void IrcMessageHandler::handleWhisperMessage(Communi::IrcMessage *ircMessage)
|
||||||
MessagePtr message = builder.build();
|
MessagePtr message = builder.build();
|
||||||
builder.triggerHighlights();
|
builder.triggerHighlights();
|
||||||
|
|
||||||
getApp()->twitch->lastUserThatWhisperedMe.set(builder.userName);
|
getIApp()->getTwitch()->setLastUserThatWhisperedMe(builder.userName);
|
||||||
|
|
||||||
if (message->flags.has(MessageFlag::ShowInMentions))
|
if (message->flags.has(MessageFlag::ShowInMentions))
|
||||||
{
|
{
|
||||||
getApp()->twitch->mentionsChannel->addMessage(message);
|
getIApp()->getTwitch()->getMentionsChannel()->addMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
c->addMessage(message);
|
c->addMessage(message);
|
||||||
|
@ -976,15 +978,16 @@ void IrcMessageHandler::handleWhisperMessage(Communi::IrcMessage *ircMessage)
|
||||||
!(getSettings()->streamerModeSuppressInlineWhispers &&
|
!(getSettings()->streamerModeSuppressInlineWhispers &&
|
||||||
getIApp()->getStreamerMode()->isEnabled()))
|
getIApp()->getStreamerMode()->isEnabled()))
|
||||||
{
|
{
|
||||||
getApp()->twitch->forEachChannel(
|
getIApp()->getTwitchAbstract()->forEachChannel(
|
||||||
[&message, overrideFlags](ChannelPtr channel) {
|
[&message, overrideFlags](ChannelPtr channel) {
|
||||||
channel->addMessage(message, overrideFlags);
|
channel->addMessage(message, overrideFlags);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IrcMessageHandler::handleUserNoticeMessage(Communi::IrcMessage *message,
|
void IrcMessageHandler::handleUserNoticeMessage(
|
||||||
TwitchIrcServer &server)
|
Communi::IrcMessage *message, ITwitchIrcServer &twitchServer,
|
||||||
|
IAbstractIrcServer &abstractIrcServer)
|
||||||
{
|
{
|
||||||
auto tags = message->tags();
|
auto tags = message->tags();
|
||||||
auto parameters = message->parameters();
|
auto parameters = message->parameters();
|
||||||
|
@ -997,7 +1000,7 @@ void IrcMessageHandler::handleUserNoticeMessage(Communi::IrcMessage *message,
|
||||||
content = parameters[1];
|
content = parameters[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
auto chn = server.getChannelOrEmpty(target);
|
auto chn = abstractIrcServer.getChannelOrEmpty(target);
|
||||||
if (isIgnoredMessage({
|
if (isIgnoredMessage({
|
||||||
.message = content,
|
.message = content,
|
||||||
.twitchUserID = tags.value("user-id").toString(),
|
.twitchUserID = tags.value("user-id").toString(),
|
||||||
|
@ -1013,7 +1016,7 @@ void IrcMessageHandler::handleUserNoticeMessage(Communi::IrcMessage *message,
|
||||||
// Messages are not required, so they might be empty
|
// Messages are not required, so they might be empty
|
||||||
if (!content.isEmpty())
|
if (!content.isEmpty())
|
||||||
{
|
{
|
||||||
this->addMessage(message, chn, content, server, true, false);
|
this->addMessage(message, chn, content, twitchServer, true, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1090,7 +1093,7 @@ void IrcMessageHandler::handleUserNoticeMessage(Communi::IrcMessage *message,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto chan = server.getChannelOrEmpty(channelName);
|
auto chan = abstractIrcServer.getChannelOrEmpty(channelName);
|
||||||
|
|
||||||
if (!chan->isEmpty())
|
if (!chan->isEmpty())
|
||||||
{
|
{
|
||||||
|
@ -1111,7 +1114,7 @@ void IrcMessageHandler::handleNoticeMessage(Communi::IrcNoticeMessage *message)
|
||||||
{
|
{
|
||||||
// Notice wasn't targeted at a single channel, send to all twitch
|
// Notice wasn't targeted at a single channel, send to all twitch
|
||||||
// channels
|
// channels
|
||||||
getApp()->twitch->forEachChannelAndSpecialChannels(
|
getIApp()->getTwitch()->forEachChannelAndSpecialChannels(
|
||||||
[msg](const auto &c) {
|
[msg](const auto &c) {
|
||||||
c->addMessage(msg);
|
c->addMessage(msg);
|
||||||
});
|
});
|
||||||
|
@ -1119,7 +1122,8 @@ void IrcMessageHandler::handleNoticeMessage(Communi::IrcNoticeMessage *message)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto channel = getApp()->twitch->getChannelOrEmpty(channelName);
|
auto channel =
|
||||||
|
getIApp()->getTwitchAbstract()->getChannelOrEmpty(channelName);
|
||||||
|
|
||||||
if (channel->isEmpty())
|
if (channel->isEmpty())
|
||||||
{
|
{
|
||||||
|
@ -1202,8 +1206,8 @@ void IrcMessageHandler::handleNoticeMessage(Communi::IrcNoticeMessage *message)
|
||||||
|
|
||||||
void IrcMessageHandler::handleJoinMessage(Communi::IrcMessage *message)
|
void IrcMessageHandler::handleJoinMessage(Communi::IrcMessage *message)
|
||||||
{
|
{
|
||||||
auto channel =
|
auto channel = getIApp()->getTwitchAbstract()->getChannelOrEmpty(
|
||||||
getApp()->twitch->getChannelOrEmpty(message->parameter(0).remove(0, 1));
|
message->parameter(0).remove(0, 1));
|
||||||
|
|
||||||
auto *twitchChannel = dynamic_cast<TwitchChannel *>(channel.get());
|
auto *twitchChannel = dynamic_cast<TwitchChannel *>(channel.get());
|
||||||
if (!twitchChannel)
|
if (!twitchChannel)
|
||||||
|
@ -1225,8 +1229,8 @@ void IrcMessageHandler::handleJoinMessage(Communi::IrcMessage *message)
|
||||||
|
|
||||||
void IrcMessageHandler::handlePartMessage(Communi::IrcMessage *message)
|
void IrcMessageHandler::handlePartMessage(Communi::IrcMessage *message)
|
||||||
{
|
{
|
||||||
auto channel =
|
auto channel = getIApp()->getTwitchAbstract()->getChannelOrEmpty(
|
||||||
getApp()->twitch->getChannelOrEmpty(message->parameter(0).remove(0, 1));
|
message->parameter(0).remove(0, 1));
|
||||||
|
|
||||||
auto *twitchChannel = dynamic_cast<TwitchChannel *>(channel.get());
|
auto *twitchChannel = dynamic_cast<TwitchChannel *>(channel.get());
|
||||||
if (!twitchChannel)
|
if (!twitchChannel)
|
||||||
|
@ -1311,7 +1315,7 @@ void IrcMessageHandler::setSimilarityFlags(const MessagePtr &message,
|
||||||
void IrcMessageHandler::addMessage(Communi::IrcMessage *message,
|
void IrcMessageHandler::addMessage(Communi::IrcMessage *message,
|
||||||
const ChannelPtr &chan,
|
const ChannelPtr &chan,
|
||||||
const QString &originalContent,
|
const QString &originalContent,
|
||||||
TwitchIrcServer &server, bool isSub,
|
ITwitchIrcServer &server, bool isSub,
|
||||||
bool isAction)
|
bool isAction)
|
||||||
{
|
{
|
||||||
if (chan->isEmpty())
|
if (chan->isEmpty())
|
||||||
|
@ -1446,7 +1450,7 @@ void IrcMessageHandler::addMessage(Communi::IrcMessage *message,
|
||||||
|
|
||||||
if (highlighted && showInMentions)
|
if (highlighted && showInMentions)
|
||||||
{
|
{
|
||||||
server.mentionsChannel->addMessage(msg);
|
server.getMentionsChannel()->addMessage(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
chan->addMessage(msg);
|
chan->addMessage(msg);
|
||||||
|
|
|
@ -9,7 +9,8 @@
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
|
||||||
class TwitchIrcServer;
|
class IAbstractIrcServer;
|
||||||
|
class ITwitchIrcServer;
|
||||||
class Channel;
|
class Channel;
|
||||||
using ChannelPtr = std::shared_ptr<Channel>;
|
using ChannelPtr = std::shared_ptr<Channel>;
|
||||||
struct Message;
|
struct Message;
|
||||||
|
@ -38,7 +39,8 @@ public:
|
||||||
std::vector<MessagePtr> &otherLoaded);
|
std::vector<MessagePtr> &otherLoaded);
|
||||||
|
|
||||||
void handlePrivMessage(Communi::IrcPrivateMessage *message,
|
void handlePrivMessage(Communi::IrcPrivateMessage *message,
|
||||||
TwitchIrcServer &server);
|
ITwitchIrcServer &twitchServer,
|
||||||
|
IAbstractIrcServer &abstractIrcServer);
|
||||||
|
|
||||||
void handleRoomStateMessage(Communi::IrcMessage *message);
|
void handleRoomStateMessage(Communi::IrcMessage *message);
|
||||||
void handleClearChatMessage(Communi::IrcMessage *message);
|
void handleClearChatMessage(Communi::IrcMessage *message);
|
||||||
|
@ -48,7 +50,8 @@ public:
|
||||||
void handleWhisperMessage(Communi::IrcMessage *ircMessage);
|
void handleWhisperMessage(Communi::IrcMessage *ircMessage);
|
||||||
|
|
||||||
void handleUserNoticeMessage(Communi::IrcMessage *message,
|
void handleUserNoticeMessage(Communi::IrcMessage *message,
|
||||||
TwitchIrcServer &server);
|
ITwitchIrcServer &twitchServer,
|
||||||
|
IAbstractIrcServer &abstractIrcServer);
|
||||||
|
|
||||||
void handleNoticeMessage(Communi::IrcNoticeMessage *message);
|
void handleNoticeMessage(Communi::IrcNoticeMessage *message);
|
||||||
|
|
||||||
|
@ -56,7 +59,7 @@ public:
|
||||||
void handlePartMessage(Communi::IrcMessage *message);
|
void handlePartMessage(Communi::IrcMessage *message);
|
||||||
|
|
||||||
void addMessage(Communi::IrcMessage *message, const ChannelPtr &chan,
|
void addMessage(Communi::IrcMessage *message, const ChannelPtr &chan,
|
||||||
const QString &originalContent, TwitchIrcServer &server,
|
const QString &originalContent, ITwitchIrcServer &server,
|
||||||
bool isSub, bool isAction);
|
bool isSub, bool isAction);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -176,7 +176,8 @@ TwitchChannel::TwitchChannel(const QString &name)
|
||||||
TwitchMessageBuilder::liveMessage(this->getDisplayName(),
|
TwitchMessageBuilder::liveMessage(this->getDisplayName(),
|
||||||
&builder2);
|
&builder2);
|
||||||
builder2.message().id = this->roomId();
|
builder2.message().id = this->roomId();
|
||||||
getApp()->twitch->liveChannel->addMessage(builder2.release());
|
getIApp()->getTwitch()->getLiveChannel()->addMessage(
|
||||||
|
builder2.release());
|
||||||
|
|
||||||
// Notify on all channels with a ping sound
|
// Notify on all channels with a ping sound
|
||||||
if (getSettings()->notificationOnAnyChannel &&
|
if (getSettings()->notificationOnAnyChannel &&
|
||||||
|
@ -198,7 +199,7 @@ TwitchChannel::TwitchChannel(const QString &name)
|
||||||
|
|
||||||
// "delete" old 'CHANNEL is live' message
|
// "delete" old 'CHANNEL is live' message
|
||||||
LimitedQueueSnapshot<MessagePtr> snapshot =
|
LimitedQueueSnapshot<MessagePtr> snapshot =
|
||||||
getApp()->twitch->liveChannel->getMessageSnapshot();
|
getIApp()->getTwitch()->getLiveChannel()->getMessageSnapshot();
|
||||||
int snapshotLength = snapshot.size();
|
int snapshotLength = snapshot.size();
|
||||||
|
|
||||||
// MSVC hates this code if the parens are not there
|
// MSVC hates this code if the parens are not there
|
||||||
|
@ -237,17 +238,18 @@ TwitchChannel::~TwitchChannel()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
getApp()->twitch->dropSeventvChannel(this->seventvUserID_,
|
getIApp()->getTwitch()->dropSeventvChannel(this->seventvUserID_,
|
||||||
this->seventvEmoteSetID_);
|
this->seventvEmoteSetID_);
|
||||||
|
|
||||||
if (getApp()->twitch->bttvLiveUpdates)
|
if (getIApp()->getTwitch()->getBTTVLiveUpdates())
|
||||||
{
|
{
|
||||||
getApp()->twitch->bttvLiveUpdates->partChannel(this->roomId());
|
getIApp()->getTwitch()->getBTTVLiveUpdates()->partChannel(
|
||||||
|
this->roomId());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getApp()->twitch->seventvEventAPI)
|
if (getIApp()->getTwitch()->getSeventvEventAPI())
|
||||||
{
|
{
|
||||||
getApp()->twitch->seventvEventAPI->unsubscribeTwitchChannel(
|
getIApp()->getTwitch()->getSeventvEventAPI()->unsubscribeTwitchChannel(
|
||||||
this->roomId());
|
this->roomId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -425,7 +427,7 @@ void TwitchChannel::addChannelPointReward(const ChannelPointReward &reward)
|
||||||
<< "] Channel point reward added:" << reward.id << ","
|
<< "] Channel point reward added:" << reward.id << ","
|
||||||
<< reward.title << "," << reward.isUserInputRequired;
|
<< reward.title << "," << reward.isUserInputRequired;
|
||||||
|
|
||||||
auto *server = getApp()->twitch;
|
auto *server = getIApp()->getTwitch();
|
||||||
auto it = std::remove_if(
|
auto it = std::remove_if(
|
||||||
this->waitingRedemptions_.begin(), this->waitingRedemptions_.end(),
|
this->waitingRedemptions_.begin(), this->waitingRedemptions_.end(),
|
||||||
[&](const QueuedRedemption &msg) {
|
[&](const QueuedRedemption &msg) {
|
||||||
|
@ -776,7 +778,7 @@ bool TwitchChannel::canReconnect() const
|
||||||
|
|
||||||
void TwitchChannel::reconnect()
|
void TwitchChannel::reconnect()
|
||||||
{
|
{
|
||||||
getApp()->twitch->connect();
|
getIApp()->getTwitchAbstract()->connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString TwitchChannel::roomId() const
|
QString TwitchChannel::roomId() const
|
||||||
|
@ -891,7 +893,7 @@ const QString &TwitchChannel::seventvEmoteSetID() const
|
||||||
|
|
||||||
void TwitchChannel::joinBttvChannel() const
|
void TwitchChannel::joinBttvChannel() const
|
||||||
{
|
{
|
||||||
if (getApp()->twitch->bttvLiveUpdates)
|
if (getIApp()->getTwitch()->getBTTVLiveUpdates())
|
||||||
{
|
{
|
||||||
const auto currentAccount =
|
const auto currentAccount =
|
||||||
getIApp()->getAccounts()->twitch.getCurrent();
|
getIApp()->getAccounts()->twitch.getCurrent();
|
||||||
|
@ -900,8 +902,8 @@ void TwitchChannel::joinBttvChannel() const
|
||||||
{
|
{
|
||||||
userName = currentAccount->getUserName();
|
userName = currentAccount->getUserName();
|
||||||
}
|
}
|
||||||
getApp()->twitch->bttvLiveUpdates->joinChannel(this->roomId(),
|
getIApp()->getTwitch()->getBTTVLiveUpdates()->joinChannel(
|
||||||
userName);
|
this->roomId(), userName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1048,14 +1050,14 @@ void TwitchChannel::updateSeventvData(const QString &newUserID,
|
||||||
this->seventvUserID_ = newUserID;
|
this->seventvUserID_ = newUserID;
|
||||||
this->seventvEmoteSetID_ = newEmoteSetID;
|
this->seventvEmoteSetID_ = newEmoteSetID;
|
||||||
runInGuiThread([this, oldUserID, oldEmoteSetID]() {
|
runInGuiThread([this, oldUserID, oldEmoteSetID]() {
|
||||||
if (getApp()->twitch->seventvEventAPI)
|
if (getIApp()->getTwitch()->getSeventvEventAPI())
|
||||||
{
|
{
|
||||||
getApp()->twitch->seventvEventAPI->subscribeUser(
|
getIApp()->getTwitch()->getSeventvEventAPI()->subscribeUser(
|
||||||
this->seventvUserID_, this->seventvEmoteSetID_);
|
this->seventvUserID_, this->seventvEmoteSetID_);
|
||||||
|
|
||||||
if (oldUserID || oldEmoteSetID)
|
if (oldUserID || oldEmoteSetID)
|
||||||
{
|
{
|
||||||
getApp()->twitch->dropSeventvChannel(
|
getIApp()->getTwitch()->dropSeventvChannel(
|
||||||
oldUserID.value_or(QString()),
|
oldUserID.value_or(QString()),
|
||||||
oldEmoteSetID.value_or(QString()));
|
oldEmoteSetID.value_or(QString()));
|
||||||
}
|
}
|
||||||
|
@ -1251,7 +1253,8 @@ void TwitchChannel::loadRecentMessages()
|
||||||
tc->addRecentChatter(msg->displayName);
|
tc->addRecentChatter(msg->displayName);
|
||||||
}
|
}
|
||||||
|
|
||||||
getApp()->twitch->mentionsChannel->fillInMissingMessages(msgs);
|
getIApp()->getTwitch()->getMentionsChannel()->fillInMissingMessages(
|
||||||
|
msgs);
|
||||||
},
|
},
|
||||||
[weak]() {
|
[weak]() {
|
||||||
auto shared = weak.lock();
|
auto shared = weak.lock();
|
||||||
|
@ -1841,9 +1844,9 @@ void TwitchChannel::updateSevenTVActivity()
|
||||||
|
|
||||||
void TwitchChannel::listenSevenTVCosmetics() const
|
void TwitchChannel::listenSevenTVCosmetics() const
|
||||||
{
|
{
|
||||||
if (getApp()->twitch->seventvEventAPI)
|
if (getIApp()->getTwitch()->getSeventvEventAPI())
|
||||||
{
|
{
|
||||||
getApp()->twitch->seventvEventAPI->subscribeTwitchChannel(
|
getIApp()->getTwitch()->getSeventvEventAPI()->subscribeTwitchChannel(
|
||||||
this->roomId());
|
this->roomId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -263,7 +263,7 @@ std::shared_ptr<Channel> TwitchIrcServer::createChannel(
|
||||||
void TwitchIrcServer::privateMessageReceived(
|
void TwitchIrcServer::privateMessageReceived(
|
||||||
Communi::IrcPrivateMessage *message)
|
Communi::IrcPrivateMessage *message)
|
||||||
{
|
{
|
||||||
IrcMessageHandler::instance().handlePrivMessage(message, *this);
|
IrcMessageHandler::instance().handlePrivMessage(message, *this, *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TwitchIrcServer::readConnectionMessageReceived(
|
void TwitchIrcServer::readConnectionMessageReceived(
|
||||||
|
@ -310,7 +310,7 @@ void TwitchIrcServer::readConnectionMessageReceived(
|
||||||
}
|
}
|
||||||
else if (command == "USERNOTICE")
|
else if (command == "USERNOTICE")
|
||||||
{
|
{
|
||||||
handler.handleUserNoticeMessage(message, *this);
|
handler.handleUserNoticeMessage(message, *this, *this);
|
||||||
}
|
}
|
||||||
else if (command == "NOTICE")
|
else if (command == "NOTICE")
|
||||||
{
|
{
|
||||||
|
@ -645,16 +645,56 @@ void TwitchIrcServer::onReplySendRequested(
|
||||||
sent = true;
|
sent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<BttvLiveUpdates> &TwitchIrcServer::getBTTVLiveUpdates()
|
||||||
|
{
|
||||||
|
return this->bttvLiveUpdates;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<SeventvEventAPI> &TwitchIrcServer::getSeventvEventAPI()
|
||||||
|
{
|
||||||
|
return this->seventvEventAPI;
|
||||||
|
}
|
||||||
|
|
||||||
const IndirectChannel &TwitchIrcServer::getWatchingChannel() const
|
const IndirectChannel &TwitchIrcServer::getWatchingChannel() const
|
||||||
{
|
{
|
||||||
return this->watchingChannel;
|
return this->watchingChannel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TwitchIrcServer::setWatchingChannel(ChannelPtr newWatchingChannel)
|
||||||
|
{
|
||||||
|
this->watchingChannel.reset(newWatchingChannel);
|
||||||
|
}
|
||||||
|
|
||||||
|
ChannelPtr TwitchIrcServer::getWhispersChannel() const
|
||||||
|
{
|
||||||
|
return this->whispersChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChannelPtr TwitchIrcServer::getMentionsChannel() const
|
||||||
|
{
|
||||||
|
return this->mentionsChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChannelPtr TwitchIrcServer::getLiveChannel() const
|
||||||
|
{
|
||||||
|
return this->liveChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChannelPtr TwitchIrcServer::getAutomodChannel() const
|
||||||
|
{
|
||||||
|
return this->automodChannel;
|
||||||
|
}
|
||||||
|
|
||||||
QString TwitchIrcServer::getLastUserThatWhisperedMe() const
|
QString TwitchIrcServer::getLastUserThatWhisperedMe() const
|
||||||
{
|
{
|
||||||
return this->lastUserThatWhisperedMe.get();
|
return this->lastUserThatWhisperedMe.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TwitchIrcServer::setLastUserThatWhisperedMe(const QString &user)
|
||||||
|
{
|
||||||
|
this->lastUserThatWhisperedMe.set(user);
|
||||||
|
}
|
||||||
|
|
||||||
void TwitchIrcServer::reloadBTTVGlobalEmotes()
|
void TwitchIrcServer::reloadBTTVGlobalEmotes()
|
||||||
{
|
{
|
||||||
getIApp()->getBttvEmotes()->loadEmotes();
|
getIApp()->getBttvEmotes()->loadEmotes();
|
||||||
|
|
|
@ -27,9 +27,27 @@ class ITwitchIrcServer
|
||||||
public:
|
public:
|
||||||
virtual ~ITwitchIrcServer() = default;
|
virtual ~ITwitchIrcServer() = default;
|
||||||
|
|
||||||
|
virtual void forEachChannelAndSpecialChannels(
|
||||||
|
std::function<void(ChannelPtr)> func) = 0;
|
||||||
|
|
||||||
|
virtual std::shared_ptr<Channel> getChannelOrEmptyByID(
|
||||||
|
const QString &channelID) = 0;
|
||||||
|
|
||||||
|
virtual void dropSeventvChannel(const QString &userID,
|
||||||
|
const QString &emoteSetID) = 0;
|
||||||
|
|
||||||
|
virtual std::unique_ptr<BttvLiveUpdates> &getBTTVLiveUpdates() = 0;
|
||||||
|
virtual std::unique_ptr<SeventvEventAPI> &getSeventvEventAPI() = 0;
|
||||||
|
|
||||||
virtual const IndirectChannel &getWatchingChannel() const = 0;
|
virtual const IndirectChannel &getWatchingChannel() const = 0;
|
||||||
|
virtual void setWatchingChannel(ChannelPtr newWatchingChannel) = 0;
|
||||||
|
virtual ChannelPtr getWhispersChannel() const = 0;
|
||||||
|
virtual ChannelPtr getMentionsChannel() const = 0;
|
||||||
|
virtual ChannelPtr getLiveChannel() const = 0;
|
||||||
|
virtual ChannelPtr getAutomodChannel() const = 0;
|
||||||
|
|
||||||
virtual QString getLastUserThatWhisperedMe() const = 0;
|
virtual QString getLastUserThatWhisperedMe() const = 0;
|
||||||
|
virtual void setLastUserThatWhisperedMe(const QString &user) = 0;
|
||||||
|
|
||||||
// Update this interface with TwitchIrcServer methods as needed
|
// Update this interface with TwitchIrcServer methods as needed
|
||||||
};
|
};
|
||||||
|
@ -44,9 +62,11 @@ public:
|
||||||
|
|
||||||
void initialize(Settings &settings, const Paths &paths) override;
|
void initialize(Settings &settings, const Paths &paths) override;
|
||||||
|
|
||||||
void forEachChannelAndSpecialChannels(std::function<void(ChannelPtr)> func);
|
void forEachChannelAndSpecialChannels(
|
||||||
|
std::function<void(ChannelPtr)> func) override;
|
||||||
|
|
||||||
std::shared_ptr<Channel> getChannelOrEmptyByID(const QString &channelID);
|
std::shared_ptr<Channel> getChannelOrEmptyByID(
|
||||||
|
const QString &channelID) override;
|
||||||
|
|
||||||
void reloadBTTVGlobalEmotes();
|
void reloadBTTVGlobalEmotes();
|
||||||
void reloadAllBTTVChannelEmotes();
|
void reloadAllBTTVChannelEmotes();
|
||||||
|
@ -68,8 +88,10 @@ public:
|
||||||
* It's currently not possible to share emote sets among users,
|
* It's currently not possible to share emote sets among users,
|
||||||
* but it's a commonly requested feature.
|
* but it's a commonly requested feature.
|
||||||
*/
|
*/
|
||||||
void dropSeventvChannel(const QString &userID, const QString &emoteSetID);
|
void dropSeventvChannel(const QString &userID,
|
||||||
|
const QString &emoteSetID) override;
|
||||||
|
|
||||||
|
private:
|
||||||
Atomic<QString> lastUserThatWhisperedMe;
|
Atomic<QString> lastUserThatWhisperedMe;
|
||||||
|
|
||||||
const ChannelPtr whispersChannel;
|
const ChannelPtr whispersChannel;
|
||||||
|
@ -81,9 +103,19 @@ public:
|
||||||
std::unique_ptr<BttvLiveUpdates> bttvLiveUpdates;
|
std::unique_ptr<BttvLiveUpdates> bttvLiveUpdates;
|
||||||
std::unique_ptr<SeventvEventAPI> seventvEventAPI;
|
std::unique_ptr<SeventvEventAPI> seventvEventAPI;
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::unique_ptr<BttvLiveUpdates> &getBTTVLiveUpdates() override;
|
||||||
|
std::unique_ptr<SeventvEventAPI> &getSeventvEventAPI() override;
|
||||||
|
|
||||||
const IndirectChannel &getWatchingChannel() const override;
|
const IndirectChannel &getWatchingChannel() const override;
|
||||||
|
void setWatchingChannel(ChannelPtr newWatchingChannel) override;
|
||||||
|
ChannelPtr getWhispersChannel() const override;
|
||||||
|
ChannelPtr getMentionsChannel() const override;
|
||||||
|
ChannelPtr getLiveChannel() const override;
|
||||||
|
ChannelPtr getAutomodChannel() const override;
|
||||||
|
|
||||||
QString getLastUserThatWhisperedMe() const override;
|
QString getLastUserThatWhisperedMe() const override;
|
||||||
|
void setLastUserThatWhisperedMe(const QString &user) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void initializeConnection(IrcConnection *connection,
|
void initializeConnection(IrcConnection *connection,
|
||||||
|
|
|
@ -236,14 +236,13 @@ void NativeMessagingServer::ReceiverThread::handleSelect(
|
||||||
}
|
}
|
||||||
|
|
||||||
postToThread([=] {
|
postToThread([=] {
|
||||||
auto *app = getApp();
|
|
||||||
|
|
||||||
if (!name.isEmpty())
|
if (!name.isEmpty())
|
||||||
{
|
{
|
||||||
auto channel = app->twitch->getOrAddChannel(name);
|
auto channel =
|
||||||
if (app->twitch->watchingChannel.get() != channel)
|
getIApp()->getTwitchAbstract()->getOrAddChannel(name);
|
||||||
|
if (getIApp()->getTwitch()->getWatchingChannel().get() != channel)
|
||||||
{
|
{
|
||||||
app->twitch->watchingChannel.reset(channel);
|
getIApp()->getTwitch()->setWatchingChannel(channel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,7 +252,8 @@ void NativeMessagingServer::ReceiverThread::handleSelect(
|
||||||
auto *window = AttachedWindow::getForeground(args);
|
auto *window = AttachedWindow::getForeground(args);
|
||||||
if (!name.isEmpty())
|
if (!name.isEmpty())
|
||||||
{
|
{
|
||||||
window->setChannel(app->twitch->getOrAddChannel(name));
|
window->setChannel(
|
||||||
|
getIApp()->getTwitchAbstract()->getOrAddChannel(name));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -294,8 +294,6 @@ void NativeMessagingServer::syncChannels(const QJsonArray &twitchChannels)
|
||||||
{
|
{
|
||||||
assertInGuiThread();
|
assertInGuiThread();
|
||||||
|
|
||||||
auto *app = getApp();
|
|
||||||
|
|
||||||
std::vector<ChannelPtr> updated;
|
std::vector<ChannelPtr> updated;
|
||||||
updated.reserve(twitchChannels.size());
|
updated.reserve(twitchChannels.size());
|
||||||
for (const auto &value : twitchChannels)
|
for (const auto &value : twitchChannels)
|
||||||
|
@ -306,7 +304,8 @@ void NativeMessagingServer::syncChannels(const QJsonArray &twitchChannels)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// the deduping is done on the extension side
|
// the deduping is done on the extension side
|
||||||
updated.emplace_back(app->twitch->getOrAddChannel(name));
|
updated.emplace_back(
|
||||||
|
getIApp()->getTwitchAbstract()->getOrAddChannel(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
// This will destroy channels that aren't used anymore.
|
// This will destroy channels that aren't used anymore.
|
||||||
|
|
|
@ -74,7 +74,7 @@ bool isBroadcasterSoftwareActive()
|
||||||
shouldShowTimeoutWarning = false;
|
shouldShowTimeoutWarning = false;
|
||||||
|
|
||||||
postToThread([] {
|
postToThread([] {
|
||||||
getApp()->twitch->addGlobalSystemMessage(
|
getIApp()->getTwitchAbstract()->addGlobalSystemMessage(
|
||||||
"Streamer Mode is set to Automatic, but pgrep timed "
|
"Streamer Mode is set to Automatic, but pgrep timed "
|
||||||
"out. This can happen if your system lagged at the "
|
"out. This can happen if your system lagged at the "
|
||||||
"wrong moment. If Streamer Mode continues to not work, "
|
"wrong moment. If Streamer Mode continues to not work, "
|
||||||
|
@ -94,7 +94,7 @@ bool isBroadcasterSoftwareActive()
|
||||||
shouldShowWarning = false;
|
shouldShowWarning = false;
|
||||||
|
|
||||||
postToThread([] {
|
postToThread([] {
|
||||||
getApp()->twitch->addGlobalSystemMessage(
|
getIApp()->getTwitchAbstract()->addGlobalSystemMessage(
|
||||||
"Streamer Mode is set to Automatic, but pgrep is "
|
"Streamer Mode is set to Automatic, but pgrep is "
|
||||||
"missing. "
|
"missing. "
|
||||||
"Install it to fix the issue or set Streamer Mode to "
|
"Install it to fix the issue or set Streamer Mode to "
|
||||||
|
|
|
@ -688,27 +688,28 @@ IndirectChannel WindowManager::decodeChannel(const SplitDescriptor &descriptor)
|
||||||
|
|
||||||
if (descriptor.type_ == "twitch")
|
if (descriptor.type_ == "twitch")
|
||||||
{
|
{
|
||||||
return app->twitch->getOrAddChannel(descriptor.channelName_);
|
return getIApp()->getTwitchAbstract()->getOrAddChannel(
|
||||||
|
descriptor.channelName_);
|
||||||
}
|
}
|
||||||
else if (descriptor.type_ == "mentions")
|
else if (descriptor.type_ == "mentions")
|
||||||
{
|
{
|
||||||
return app->twitch->mentionsChannel;
|
return getIApp()->getTwitch()->getMentionsChannel();
|
||||||
}
|
}
|
||||||
else if (descriptor.type_ == "watching")
|
else if (descriptor.type_ == "watching")
|
||||||
{
|
{
|
||||||
return app->twitch->watchingChannel;
|
return getIApp()->getTwitch()->getWatchingChannel();
|
||||||
}
|
}
|
||||||
else if (descriptor.type_ == "whispers")
|
else if (descriptor.type_ == "whispers")
|
||||||
{
|
{
|
||||||
return app->twitch->whispersChannel;
|
return getIApp()->getTwitch()->getWhispersChannel();
|
||||||
}
|
}
|
||||||
else if (descriptor.type_ == "live")
|
else if (descriptor.type_ == "live")
|
||||||
{
|
{
|
||||||
return app->twitch->liveChannel;
|
return getIApp()->getTwitch()->getLiveChannel();
|
||||||
}
|
}
|
||||||
else if (descriptor.type_ == "automod")
|
else if (descriptor.type_ == "automod")
|
||||||
{
|
{
|
||||||
return app->twitch->automodChannel;
|
return getIApp()->getTwitch()->getAutomodChannel();
|
||||||
}
|
}
|
||||||
else if (descriptor.type_ == "irc")
|
else if (descriptor.type_ == "irc")
|
||||||
{
|
{
|
||||||
|
@ -717,7 +718,8 @@ IndirectChannel WindowManager::decodeChannel(const SplitDescriptor &descriptor)
|
||||||
}
|
}
|
||||||
else if (descriptor.type_ == "misc")
|
else if (descriptor.type_ == "misc")
|
||||||
{
|
{
|
||||||
return app->twitch->getChannelOrEmpty(descriptor.channelName_);
|
return getIApp()->getTwitchAbstract()->getChannelOrEmpty(
|
||||||
|
descriptor.channelName_);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Channel::getEmpty();
|
return Channel::getEmpty();
|
||||||
|
|
|
@ -54,7 +54,8 @@ bool FramelessEmbedWindow::nativeEvent(const QByteArray &eventType,
|
||||||
auto channelName = root.value("channel-name").toString();
|
auto channelName = root.value("channel-name").toString();
|
||||||
|
|
||||||
this->split_->setChannel(
|
this->split_->setChannel(
|
||||||
getApp()->twitch->getOrAddChannel(channelName));
|
getIApp()->getTwitchAbstract()->getOrAddChannel(
|
||||||
|
channelName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -254,7 +254,7 @@ void Window::addDebugStuff(HotkeyController::HotkeyMap &actions)
|
||||||
const auto &messages = getSampleMiscMessages();
|
const auto &messages = getSampleMiscMessages();
|
||||||
static int index = 0;
|
static int index = 0;
|
||||||
const auto &msg = messages[index++ % messages.size()];
|
const auto &msg = messages[index++ % messages.size()];
|
||||||
getApp()->twitch->addFakeMessage(msg);
|
getIApp()->getTwitchAbstract()->addFakeMessage(msg);
|
||||||
return "";
|
return "";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -262,7 +262,7 @@ void Window::addDebugStuff(HotkeyController::HotkeyMap &actions)
|
||||||
const auto &messages = getSampleCheerMessages();
|
const auto &messages = getSampleCheerMessages();
|
||||||
static int index = 0;
|
static int index = 0;
|
||||||
const auto &msg = messages[index++ % messages.size()];
|
const auto &msg = messages[index++ % messages.size()];
|
||||||
getApp()->twitch->addFakeMessage(msg);
|
getIApp()->getTwitchAbstract()->addFakeMessage(msg);
|
||||||
return "";
|
return "";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -270,7 +270,7 @@ void Window::addDebugStuff(HotkeyController::HotkeyMap &actions)
|
||||||
const auto &messages = getSampleLinkMessages();
|
const auto &messages = getSampleLinkMessages();
|
||||||
static int index = 0;
|
static int index = 0;
|
||||||
const auto &msg = messages[index++ % messages.size()];
|
const auto &msg = messages[index++ % messages.size()];
|
||||||
getApp()->twitch->addFakeMessage(msg);
|
getIApp()->getTwitchAbstract()->addFakeMessage(msg);
|
||||||
return "";
|
return "";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -286,7 +286,8 @@ void Window::addDebugStuff(HotkeyController::HotkeyMap &actions)
|
||||||
oMessage->toInner<PubSubMessageMessage>()
|
oMessage->toInner<PubSubMessageMessage>()
|
||||||
->toInner<PubSubCommunityPointsChannelV1Message>();
|
->toInner<PubSubCommunityPointsChannelV1Message>();
|
||||||
|
|
||||||
app->twitch->addFakeMessage(getSampleChannelRewardIRCMessage());
|
getIApp()->getTwitchAbstract()->addFakeMessage(
|
||||||
|
getSampleChannelRewardIRCMessage());
|
||||||
getIApp()->getTwitchPubSub()->pointReward.redeemed.invoke(
|
getIApp()->getTwitchPubSub()->pointReward.redeemed.invoke(
|
||||||
oInnerMessage->data.value("redemption").toObject());
|
oInnerMessage->data.value("redemption").toObject());
|
||||||
alt = !alt;
|
alt = !alt;
|
||||||
|
@ -309,7 +310,7 @@ void Window::addDebugStuff(HotkeyController::HotkeyMap &actions)
|
||||||
const auto &messages = getSampleEmoteTestMessages();
|
const auto &messages = getSampleEmoteTestMessages();
|
||||||
static int index = 0;
|
static int index = 0;
|
||||||
const auto &msg = messages[index++ % messages.size()];
|
const auto &msg = messages[index++ % messages.size()];
|
||||||
getApp()->twitch->addFakeMessage(msg);
|
getIApp()->getTwitchAbstract()->addFakeMessage(msg);
|
||||||
return "";
|
return "";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -317,7 +318,7 @@ void Window::addDebugStuff(HotkeyController::HotkeyMap &actions)
|
||||||
const auto &messages = getSampleSubMessages();
|
const auto &messages = getSampleSubMessages();
|
||||||
static int index = 0;
|
static int index = 0;
|
||||||
const auto &msg = messages[index++ % messages.size()];
|
const auto &msg = messages[index++ % messages.size()];
|
||||||
getApp()->twitch->addFakeMessage(msg);
|
getIApp()->getTwitchAbstract()->addFakeMessage(msg);
|
||||||
return "";
|
return "";
|
||||||
});
|
});
|
||||||
#endif
|
#endif
|
||||||
|
@ -480,8 +481,8 @@ void Window::addShortcuts()
|
||||||
splitContainer = this->notebook_->getOrAddSelectedPage();
|
splitContainer = this->notebook_->getOrAddSelectedPage();
|
||||||
}
|
}
|
||||||
Split *split = new Split(splitContainer);
|
Split *split = new Split(splitContainer);
|
||||||
split->setChannel(
|
split->setChannel(getIApp()->getTwitchAbstract()->getOrAddChannel(
|
||||||
getApp()->twitch->getOrAddChannel(si.channelName));
|
si.channelName));
|
||||||
split->setFilters(si.filters);
|
split->setFilters(si.filters);
|
||||||
splitContainer->insertSplit(split);
|
splitContainer->insertSplit(split);
|
||||||
splitContainer->setSelected(split);
|
splitContainer->setSelected(split);
|
||||||
|
|
|
@ -375,35 +375,33 @@ IndirectChannel SelectChannelDialog::getSelectedChannel() const
|
||||||
return this->selectedChannel_;
|
return this->selectedChannel_;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto *app = getApp();
|
|
||||||
|
|
||||||
switch (this->ui_.notebook->getSelectedIndex())
|
switch (this->ui_.notebook->getSelectedIndex())
|
||||||
{
|
{
|
||||||
case TAB_TWITCH: {
|
case TAB_TWITCH: {
|
||||||
if (this->ui_.twitch.channel->isChecked())
|
if (this->ui_.twitch.channel->isChecked())
|
||||||
{
|
{
|
||||||
return app->twitch->getOrAddChannel(
|
return getIApp()->getTwitchAbstract()->getOrAddChannel(
|
||||||
this->ui_.twitch.channelName->text().trimmed());
|
this->ui_.twitch.channelName->text().trimmed());
|
||||||
}
|
}
|
||||||
else if (this->ui_.twitch.watching->isChecked())
|
else if (this->ui_.twitch.watching->isChecked())
|
||||||
{
|
{
|
||||||
return app->twitch->watchingChannel;
|
return getIApp()->getTwitch()->getWatchingChannel();
|
||||||
}
|
}
|
||||||
else if (this->ui_.twitch.mentions->isChecked())
|
else if (this->ui_.twitch.mentions->isChecked())
|
||||||
{
|
{
|
||||||
return app->twitch->mentionsChannel;
|
return getIApp()->getTwitch()->getMentionsChannel();
|
||||||
}
|
}
|
||||||
else if (this->ui_.twitch.whispers->isChecked())
|
else if (this->ui_.twitch.whispers->isChecked())
|
||||||
{
|
{
|
||||||
return app->twitch->whispersChannel;
|
return getIApp()->getTwitch()->getWhispersChannel();
|
||||||
}
|
}
|
||||||
else if (this->ui_.twitch.live->isChecked())
|
else if (this->ui_.twitch.live->isChecked())
|
||||||
{
|
{
|
||||||
return app->twitch->liveChannel;
|
return getIApp()->getTwitch()->getLiveChannel();
|
||||||
}
|
}
|
||||||
else if (this->ui_.twitch.automod->isChecked())
|
else if (this->ui_.twitch.automod->isChecked())
|
||||||
{
|
{
|
||||||
return app->twitch->automodChannel;
|
return getIApp()->getTwitch()->getAutomodChannel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -298,21 +298,23 @@ UserInfoPopup::UserInfoPopup(bool closeAutomatically, Split *split)
|
||||||
menu->addAction(
|
menu->addAction(
|
||||||
"Open channel in a new popup window", this,
|
"Open channel in a new popup window", this,
|
||||||
[loginName] {
|
[loginName] {
|
||||||
auto *app = getApp();
|
auto *app = getIApp();
|
||||||
auto &window = app->getWindows()->createWindow(
|
auto &window = app->getWindows()->createWindow(
|
||||||
WindowType::Popup, true);
|
WindowType::Popup, true);
|
||||||
auto *split = window.getNotebook()
|
auto *split = window.getNotebook()
|
||||||
.getOrAddSelectedPage()
|
.getOrAddSelectedPage()
|
||||||
->appendNewSplit(false);
|
->appendNewSplit(false);
|
||||||
split->setChannel(app->twitch->getOrAddChannel(
|
split->setChannel(
|
||||||
|
app->getTwitchAbstract()->getOrAddChannel(
|
||||||
loginName.toLower()));
|
loginName.toLower()));
|
||||||
});
|
});
|
||||||
|
|
||||||
menu->addAction(
|
menu->addAction(
|
||||||
"Open channel in a new tab", this, [loginName] {
|
"Open channel in a new tab", this, [loginName] {
|
||||||
ChannelPtr channel =
|
ChannelPtr channel =
|
||||||
getApp()->twitch->getOrAddChannel(
|
getIApp()
|
||||||
loginName);
|
->getTwitchAbstract()
|
||||||
|
->getOrAddChannel(loginName);
|
||||||
auto &nb = getApp()
|
auto &nb = getApp()
|
||||||
->getWindows()
|
->getWindows()
|
||||||
->getMainWindow()
|
->getMainWindow()
|
||||||
|
|
|
@ -21,7 +21,8 @@ NewPopupItem::NewPopupItem(const QString &channelName)
|
||||||
|
|
||||||
void NewPopupItem::action()
|
void NewPopupItem::action()
|
||||||
{
|
{
|
||||||
auto channel = getApp()->twitch->getOrAddChannel(this->channelName_);
|
auto channel =
|
||||||
|
getIApp()->getTwitchAbstract()->getOrAddChannel(this->channelName_);
|
||||||
getIApp()->getWindows()->openInPopup(channel);
|
getIApp()->getWindows()->openInPopup(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,8 @@ void NewTabItem::action()
|
||||||
SplitContainer *container = nb.addPage(true);
|
SplitContainer *container = nb.addPage(true);
|
||||||
|
|
||||||
Split *split = new Split(container);
|
Split *split = new Split(container);
|
||||||
split->setChannel(getApp()->twitch->getOrAddChannel(this->channelName_));
|
split->setChannel(
|
||||||
|
getIApp()->getTwitchAbstract()->getOrAddChannel(this->channelName_));
|
||||||
container->insertSplit(split);
|
container->insertSplit(split);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1383,17 +1383,20 @@ MessageElementFlags ChannelView::getFlags() const
|
||||||
{
|
{
|
||||||
flags.set(MessageElementFlag::ModeratorTools);
|
flags.set(MessageElementFlag::ModeratorTools);
|
||||||
}
|
}
|
||||||
if (this->underlyingChannel_ == app->twitch->mentionsChannel ||
|
if (this->underlyingChannel_ ==
|
||||||
this->underlyingChannel_ == app->twitch->liveChannel ||
|
getIApp()->getTwitch()->getMentionsChannel() ||
|
||||||
this->underlyingChannel_ == app->twitch->automodChannel)
|
this->underlyingChannel_ ==
|
||||||
|
getIApp()->getTwitch()->getLiveChannel() ||
|
||||||
|
this->underlyingChannel_ ==
|
||||||
|
getIApp()->getTwitch()->getAutomodChannel())
|
||||||
{
|
{
|
||||||
flags.set(MessageElementFlag::ChannelName);
|
flags.set(MessageElementFlag::ChannelName);
|
||||||
flags.unset(MessageElementFlag::ChannelPointReward);
|
flags.unset(MessageElementFlag::ChannelPointReward);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->sourceChannel_ == app->twitch->mentionsChannel ||
|
if (this->sourceChannel_ == getIApp()->getTwitch()->getMentionsChannel() ||
|
||||||
this->sourceChannel_ == app->twitch->automodChannel)
|
this->sourceChannel_ == getIApp()->getTwitch()->getAutomodChannel())
|
||||||
{
|
{
|
||||||
flags.set(MessageElementFlag::ChannelName);
|
flags.set(MessageElementFlag::ChannelName);
|
||||||
}
|
}
|
||||||
|
@ -1546,8 +1549,8 @@ void ChannelView::drawMessages(QPainter &painter, const QRect &area)
|
||||||
|
|
||||||
.canvasWidth = this->width(),
|
.canvasWidth = this->width(),
|
||||||
.isWindowFocused = this->window() == QApplication::activeWindow(),
|
.isWindowFocused = this->window() == QApplication::activeWindow(),
|
||||||
.isMentions =
|
.isMentions = this->underlyingChannel_ ==
|
||||||
this->underlyingChannel_ == getApp()->twitch->mentionsChannel,
|
getIApp()->getTwitch()->getMentionsChannel(),
|
||||||
|
|
||||||
.y = int(-(messagesSnapshot[start]->getHeight() *
|
.y = int(-(messagesSnapshot[start]->getHeight() *
|
||||||
(fmod(this->scrollBar_->getRelativeCurrentValue(), 1)))),
|
(fmod(this->scrollBar_->getRelativeCurrentValue(), 1)))),
|
||||||
|
@ -2707,8 +2710,8 @@ void ChannelView::showUserInfoPopup(const QString &userName,
|
||||||
auto *userPopup =
|
auto *userPopup =
|
||||||
new UserInfoPopup(getSettings()->autoCloseUserPopup, this->split_);
|
new UserInfoPopup(getSettings()->autoCloseUserPopup, this->split_);
|
||||||
|
|
||||||
auto contextChannel =
|
auto contextChannel = getIApp()->getTwitchAbstract()->getChannelOrEmpty(
|
||||||
getApp()->twitch->getChannelOrEmpty(alternativePopoutChannel);
|
alternativePopoutChannel);
|
||||||
auto openingChannel = this->hasSourceChannel() ? this->sourceChannel_
|
auto openingChannel = this->hasSourceChannel() ? this->sourceChannel_
|
||||||
: this->underlyingChannel_;
|
: this->underlyingChannel_;
|
||||||
userPopup->setData(userName, contextChannel, openingChannel);
|
userPopup->setData(userName, contextChannel, openingChannel);
|
||||||
|
|
|
@ -570,7 +570,7 @@ void GeneralPage::initLayout(GeneralPageView &layout)
|
||||||
// as an official description from 7TV devs is best
|
// as an official description from 7TV devs is best
|
||||||
s.showUnlistedSevenTVEmotes.connect(
|
s.showUnlistedSevenTVEmotes.connect(
|
||||||
[]() {
|
[]() {
|
||||||
getApp()->twitch->forEachChannelAndSpecialChannels(
|
getIApp()->getTwitch()->forEachChannelAndSpecialChannels(
|
||||||
[](const auto &c) {
|
[](const auto &c) {
|
||||||
if (c->isTwitchChannel())
|
if (c->isTwitchChannel())
|
||||||
{
|
{
|
||||||
|
|
|
@ -272,7 +272,7 @@ Split::Split(QWidget *parent)
|
||||||
std::ignore = this->view_->openChannelIn.connect(
|
std::ignore = this->view_->openChannelIn.connect(
|
||||||
[this](QString twitchChannel, FromTwitchLinkOpenChannelIn openIn) {
|
[this](QString twitchChannel, FromTwitchLinkOpenChannelIn openIn) {
|
||||||
ChannelPtr channel =
|
ChannelPtr channel =
|
||||||
getApp()->twitch->getOrAddChannel(twitchChannel);
|
getIApp()->getTwitchAbstract()->getOrAddChannel(twitchChannel);
|
||||||
switch (openIn)
|
switch (openIn)
|
||||||
{
|
{
|
||||||
case FromTwitchLinkOpenChannelIn::Split:
|
case FromTwitchLinkOpenChannelIn::Split:
|
||||||
|
|
Loading…
Reference in a new issue