Huge refactor

- Remove some underscore-prefixes
 - Start using this-> more
 - Remove a few of the singletons (We pass references to managers to
         things that need it now. Might not be much better, but for now
         it works. It also shows what places might be slightly wrong
         designed)
This commit is contained in:
Rasmus Karlsson 2017-06-13 21:13:58 +02:00
parent 55b04ee7eb
commit 59d383c161
37 changed files with 630 additions and 523 deletions

View file

@ -47,6 +47,7 @@ win32 {
SOURCES += \ SOURCES += \
src/main.cpp \ src/main.cpp \
src/application.cpp \
src/channel.cpp \ src/channel.cpp \
src/colorscheme.cpp \ src/colorscheme.cpp \
src/emojis.cpp \ src/emojis.cpp \

42
src/application.cpp Normal file
View file

@ -0,0 +1,42 @@
#include "application.hpp"
#include "colorscheme.hpp"
#include "settingsmanager.hpp"
namespace chatterino {
Application::Application()
: windowManager(this->channelManager)
, emoteManager(this->windowManager, this->resources)
, resources(this->emoteManager, this->windowManager)
, channelManager(this->windowManager, this->emoteManager, this->ircManager)
, ircManager(this->channelManager, this->resources, this->emoteManager, this->windowManager)
{
// TODO(pajlada): Get rid of all singletons
ColorScheme::getInstance().init(this->windowManager);
// Initialize everything we need
this->emoteManager.loadGlobalEmotes();
// XXX
SettingsManager::getInstance().updateWordTypeMask();
this->windowManager.load();
}
Application::~Application()
{
this->windowManager.save();
}
int Application::run(QApplication &qtApp)
{
// Start connecting to the IRC Servers (Twitch only for now)
this->ircManager.connect();
// Show main window
this->windowManager.getMainWindow().show();
return qtApp.exec();
}
} // namespace chatterino

28
src/application.hpp Normal file
View file

@ -0,0 +1,28 @@
#pragma once
#include "channelmanager.hpp"
#include "emotemanager.hpp"
#include "ircmanager.hpp"
#include "resources.hpp"
#include "windowmanager.hpp"
#include <QApplication>
namespace chatterino {
class Application
{
public:
Application();
~Application();
int run(QApplication &qtApp);
WindowManager windowManager;
EmoteManager emoteManager;
Resources resources;
ChannelManager channelManager;
IrcManager ircManager;
};
} // namespace chatterino

View file

@ -3,7 +3,6 @@
#include "ircmanager.hpp" #include "ircmanager.hpp"
#include "logging/loggingmanager.hpp" #include "logging/loggingmanager.hpp"
#include "messages/message.hpp" #include "messages/message.hpp"
#include "util/urlfetch.hpp"
#include "windowmanager.hpp" #include "windowmanager.hpp"
#include <QDebug> #include <QDebug>
@ -21,8 +20,12 @@ using namespace chatterino::messages;
namespace chatterino { namespace chatterino {
Channel::Channel(const QString &channel) Channel::Channel(WindowManager &_windowManager, EmoteManager &_emoteManager,
: _messages() IrcManager &_ircManager, const QString &channel, bool isSpecial)
: windowManager(_windowManager)
, emoteManager(_emoteManager)
, ircManager(_ircManager)
, _messages()
, _name((channel.length() > 0 && channel[0] == '#') ? channel.mid(1) : channel) , _name((channel.length() > 0 && channel[0] == '#') ? channel.mid(1) : channel)
, _bttvChannelEmotes() , _bttvChannelEmotes()
, _ffzChannelEmotes() , _ffzChannelEmotes()
@ -33,7 +36,9 @@ Channel::Channel(const QString &channel)
{ {
qDebug() << "Open channel:" << channel << ". Name: " << _name; qDebug() << "Open channel:" << channel << ". Name: " << _name;
printf("Channel pointer: %p\n", this); printf("Channel pointer: %p\n", this);
reloadChannelEmotes(); if (!isSpecial) {
this->reloadChannelEmotes();
}
} }
// //
@ -121,82 +126,21 @@ void Channel::addMessage(std::shared_ptr<Message> message)
this->messageAppended(message); this->messageAppended(message);
WindowManager::getInstance().repaintVisibleChatWidgets(this); this->windowManager.repaintVisibleChatWidgets(this);
} }
// private methods // private methods
void Channel::reloadChannelEmotes() void Channel::reloadChannelEmotes()
{ {
reloadBttvEmotes(); printf("[Channel:%s] Reloading channel emotes\n", qPrintable(this->_name));
reloadFfzEmotes(); this->emoteManager.reloadBTTVChannelEmotes(this->_name, this->_bttvChannelEmotes);
this->emoteManager.reloadFFZChannelEmotes(this->_name, this->_ffzChannelEmotes);
} }
void Channel::sendMessage(const QString &message) void Channel::sendMessage(const QString &message)
{ {
qDebug() << "Channel send message: " << message; qDebug() << "Channel send message: " << message;
IrcManager &instance = IrcManager::getInstance(); this->ircManager.sendMessage(_name, message);
instance.sendMessage(_name, message);
}
void Channel::reloadBttvEmotes()
{
util::urlJsonFetch(
"https://api.betterttv.net/2/channels/" + _name, [this](QJsonObject &rootNode) {
auto emotesNode = rootNode.value("emotes").toArray();
QString linkTemplate = "https:" + rootNode.value("urlTemplate").toString();
for (const QJsonValue &emoteNode : emotesNode) {
QJsonObject emoteObject = emoteNode.toObject();
QString id = emoteObject.value("id").toString();
QString code = emoteObject.value("code").toString();
// emoteObject.value("imageType").toString();
QString link = linkTemplate;
link.detach();
link = link.replace("{{id}}", id).replace("{{image}}", "1x");
auto emote = EmoteManager::getInstance().getBttvChannelEmoteFromCaches().getOrAdd(
id, [&code, &link] {
return new LazyLoadedImage(link, 1, code, code + "\nChannel Bttv Emote");
});
this->getBttvChannelEmotes().insert(code, emote);
}
});
}
void Channel::reloadFfzEmotes()
{
util::urlJsonFetch("http://api.frankerfacez.com/v1/room/" + _name, [this](
QJsonObject &rootNode) {
auto setsNode = rootNode.value("sets").toObject();
for (const QJsonValue &setNode : setsNode) {
auto emotesNode = setNode.toObject().value("emoticons").toArray();
for (const QJsonValue &emoteNode : emotesNode) {
QJsonObject emoteObject = emoteNode.toObject();
// margins
int id = emoteObject.value("id").toInt();
QString code = emoteObject.value("name").toString();
QJsonObject urls = emoteObject.value("urls").toObject();
QString url1 = "http:" + urls.value("1").toString();
auto emote = EmoteManager::getInstance().getFfzChannelEmoteFromCaches().getOrAdd(
id, [&code, &url1] {
return new LazyLoadedImage(url1, 1, code, code + "\nGlobal Ffz Emote");
});
getFfzChannelEmotes().insert(code, emote);
}
}
});
} }
} // namespace chatterino } // namespace chatterino

View file

@ -18,12 +18,15 @@ namespace messages {
class Message; class Message;
} }
class ChannelManager; class WindowManager;
class EmoteManager;
class IrcManager;
class Channel class Channel
{ {
public: public:
Channel(const QString &channel); explicit Channel(WindowManager &_windowManager, EmoteManager &_emoteManager,
IrcManager &_ircManager, const QString &channel, bool isSpecial = false);
boost::signals2::signal<void(messages::SharedMessage &)> messageRemovedFromStart; boost::signals2::signal<void(messages::SharedMessage &)> messageRemovedFromStart;
boost::signals2::signal<void(messages::SharedMessage &)> messageAppended; boost::signals2::signal<void(messages::SharedMessage &)> messageAppended;
@ -51,6 +54,10 @@ public:
void sendMessage(const QString &message); void sendMessage(const QString &message);
private: private:
WindowManager &windowManager;
EmoteManager &emoteManager;
IrcManager &ircManager;
// variabeles // variabeles
messages::LimitedQueue<messages::SharedMessage> _messages; messages::LimitedQueue<messages::SharedMessage> _messages;
@ -69,10 +76,6 @@ private:
QString _streamStatus; QString _streamStatus;
QString _streamGame; QString _streamGame;
// std::shared_ptr<logging::Channel> _loggingChannel; // std::shared_ptr<logging::Channel> _loggingChannel;
// methods
void reloadBttvEmotes();
void reloadFfzEmotes();
}; };
} // namespace chatterino } // namespace chatterino

View file

@ -3,14 +3,14 @@
namespace chatterino { namespace chatterino {
ChannelManager ChannelManager::instance; ChannelManager::ChannelManager(WindowManager &_windowManager, EmoteManager &_emoteManager,
IrcManager &_ircManager)
ChannelManager::ChannelManager() : windowManager(_windowManager)
: _channels() , emoteManager(_emoteManager)
, _channelsMutex() , ircManager(_ircManager)
, _whispers(new Channel(QString("/whispers"))) , _whispers(new Channel(_windowManager, _emoteManager, _ircManager, "/whispers", true))
, _mentions(new Channel(QString("/mentions"))) , _mentions(new Channel(_windowManager, _emoteManager, _ircManager, "/mentions", true))
, _empty(new Channel(QString(""))) , _empty(new Channel(_windowManager, _emoteManager, _ircManager, QString(), true))
{ {
} }
@ -55,10 +55,11 @@ std::shared_ptr<Channel> ChannelManager::addChannel(const QString &channel)
auto it = _channels.find(channelName); auto it = _channels.find(channelName);
if (it == _channels.end()) { if (it == _channels.end()) {
auto channel = std::shared_ptr<Channel>(new Channel(channelName)); auto channel = std::shared_ptr<Channel>(
new Channel(this->windowManager, this->emoteManager, this->ircManager, channelName));
_channels.insert(channelName, std::make_tuple(channel, 1)); _channels.insert(channelName, std::make_tuple(channel, 1));
IrcManager::getInstance().joinChannel(channelName); this->ircManager.joinChannel(channelName);
return channel; return channel;
} }
@ -114,7 +115,7 @@ void ChannelManager::removeChannel(const QString &channel)
std::get<1>(a.value())--; std::get<1>(a.value())--;
if (std::get<1>(a.value()) == 0) { if (std::get<1>(a.value()) == 0) {
IrcManager::getInstance().partChannel(c); this->ircManager.partChannel(c);
_channels.remove(c); _channels.remove(c);
} }
} }

View file

@ -4,13 +4,15 @@
namespace chatterino { namespace chatterino {
class WindowManager;
class EmoteManager;
class IrcManager;
class ChannelManager class ChannelManager
{ {
public: public:
static ChannelManager &getInstance() explicit ChannelManager(WindowManager &_windowManager, EmoteManager &_emoteManager,
{ IrcManager &_ircManager);
return instance;
}
std::shared_ptr<Channel> getWhispers(); std::shared_ptr<Channel> getWhispers();
std::shared_ptr<Channel> getMentions(); std::shared_ptr<Channel> getMentions();
@ -23,9 +25,9 @@ public:
void removeChannel(const QString &channel); void removeChannel(const QString &channel);
private: private:
static ChannelManager instance; WindowManager &windowManager;
EmoteManager &emoteManager;
ChannelManager(); IrcManager &ircManager;
QMap<QString, std::tuple<std::shared_ptr<Channel>, int>> _channels; QMap<QString, std::tuple<std::shared_ptr<Channel>, int>> _channels;
QMutex _channelsMutex; QMutex _channelsMutex;

View file

@ -8,20 +8,25 @@
namespace chatterino { namespace chatterino {
void ColorScheme::init() void ColorScheme::init(WindowManager &windowManager)
{ {
static bool initiated = false; static bool initiated = false;
if (!initiated) { if (!initiated) {
initiated = true; initiated = true;
ColorScheme::getInstance().update(); ColorScheme::getInstance().update();
SettingsManager::getInstance().theme.valueChanged.connect(
[](const QString &) { ColorScheme::getInstance().update(); });
SettingsManager::getInstance().themeHue.valueChanged.connect(
[](const float &) { ColorScheme::getInstance().update(); });
ColorScheme::getInstance().updated.connect( SettingsManager::getInstance().theme.valueChanged.connect([](const QString &) {
[] { WindowManager::getInstance().repaintVisibleChatWidgets(); }); ColorScheme::getInstance().update(); //
});
SettingsManager::getInstance().themeHue.valueChanged.connect([](const float &) {
ColorScheme::getInstance().update(); //
});
ColorScheme::getInstance().updated.connect([&windowManager] {
windowManager.repaintVisibleChatWidgets(); //
});
} }
} }

View file

@ -6,6 +6,8 @@
namespace chatterino { namespace chatterino {
class WindowManager;
class ColorScheme class ColorScheme
{ {
public: public:
@ -67,7 +69,7 @@ public:
return instance; return instance;
} }
void init(); void init(WindowManager &windowManager);
void normalizeColor(QColor &color); void normalizeColor(QColor &color);
void update(); void update();

View file

@ -46,8 +46,14 @@ void Emojis::parseEmojis(std::vector<std::tuple<messages::LazyLoadedImage *, QSt
} }
vector.push_back(std::tuple<messages::LazyLoadedImage *, QString>( vector.push_back(std::tuple<messages::LazyLoadedImage *, QString>(
imageCache.getOrAdd( imageCache.getOrAdd(url,
url, [&url] { return new messages::LazyLoadedImage(url, 0.35); }), [/*&url*/] {
/* TODO: re-implement
return new messages::LazyLoadedImage(url,
0.35); //
*/
return nullptr;
}),
QString())); QString()));
i += j - 1; i += j - 1;

View file

@ -1,5 +1,7 @@
#include "emotemanager.hpp" #include "emotemanager.hpp"
#include "resources.hpp" #include "resources.hpp"
#include "util/urlfetch.hpp"
#include "windowmanager.hpp"
#include <QDebug> #include <QDebug>
#include <QJsonArray> #include <QJsonArray>
@ -18,22 +20,92 @@ using namespace chatterino::messages;
namespace chatterino { namespace chatterino {
EmoteManager EmoteManager::instance; EmoteManager::EmoteManager(WindowManager &_windowManager, Resources &_resources)
: windowManager(_windowManager)
EmoteManager::EmoteManager() , resources(_resources)
: _twitchEmotes()
, _bttvEmotes()
, _ffzEmotes()
, _chatterinoEmotes()
, _bttvChannelEmoteFromCaches()
, _ffzChannelEmoteFromCaches()
, _twitchEmoteFromCache()
, _miscImageFromCache()
, _gifUpdateTimerSignal()
, _gifUpdateTimer()
, _gifUpdateTimerInitiated(false)
, _generation(0)
{ {
// Note: Do not use this->resources in ctor
}
void EmoteManager::loadGlobalEmotes()
{
this->loadBTTVEmotes();
this->loadFFZEmotes();
}
void EmoteManager::reloadBTTVChannelEmotes(const QString &channelName,
BTTVEmoteMap &channelEmoteMap)
{
printf("[EmoteManager] Reload BTTV Channel Emotes for channel %s\n", qPrintable(channelName));
QString url("https://api.betterttv.net/2/channels/" + channelName);
util::urlJsonFetch(url, [this, &channelEmoteMap](QJsonObject &rootNode) {
channelEmoteMap.clear();
auto emotesNode = rootNode.value("emotes").toArray();
QString linkTemplate = "https:" + rootNode.value("urlTemplate").toString();
for (const QJsonValue &emoteNode : emotesNode) {
QJsonObject emoteObject = emoteNode.toObject();
QString id = emoteObject.value("id").toString();
QString code = emoteObject.value("code").toString();
// emoteObject.value("imageType").toString();
QString link = linkTemplate;
link.detach();
link = link.replace("{{id}}", id).replace("{{image}}", "1x");
auto emote = this->getBTTVChannelEmoteFromCaches().getOrAdd(id, [this, &code, &link] {
return new LazyLoadedImage(*this, this->windowManager, link, 1, code,
code + "\nChannel BTTV Emote");
});
this->bttvChannelEmotes.insert(code, emote);
channelEmoteMap.insert(code, emote);
}
});
}
void EmoteManager::reloadFFZChannelEmotes(
const QString &channelName,
ConcurrentMap<QString, messages::LazyLoadedImage *> &channelEmoteMap)
{
printf("[EmoteManager] Reload FFZ Channel Emotes for channel %s\n", qPrintable(channelName));
QString url("http://api.frankerfacez.com/v1/room/" + channelName);
util::urlJsonFetch(url, [this, &channelEmoteMap](QJsonObject &rootNode) {
channelEmoteMap.clear();
auto setsNode = rootNode.value("sets").toObject();
for (const QJsonValue &setNode : setsNode) {
auto emotesNode = setNode.toObject().value("emoticons").toArray();
for (const QJsonValue &emoteNode : emotesNode) {
QJsonObject emoteObject = emoteNode.toObject();
// margins
int id = emoteObject.value("id").toInt();
QString code = emoteObject.value("name").toString();
QJsonObject urls = emoteObject.value("urls").toObject();
QString url1 = "http:" + urls.value("1").toString();
auto emote =
this->getFFZChannelEmoteFromCaches().getOrAdd(id, [this, &code, &url1] {
return new LazyLoadedImage(*this, this->windowManager, url1, 1, code,
code + "\nGlobal FFZ Emote");
});
this->ffzChannelEmotes.insert(code, emote);
channelEmoteMap.insert(code, emote);
}
}
});
} }
ConcurrentMap<QString, twitch::EmoteValue *> &EmoteManager::getTwitchEmotes() ConcurrentMap<QString, twitch::EmoteValue *> &EmoteManager::getTwitchEmotes()
@ -41,12 +113,12 @@ ConcurrentMap<QString, twitch::EmoteValue *> &EmoteManager::getTwitchEmotes()
return _twitchEmotes; return _twitchEmotes;
} }
ConcurrentMap<QString, messages::LazyLoadedImage *> &EmoteManager::getBttvEmotes() ConcurrentMap<QString, messages::LazyLoadedImage *> &EmoteManager::getBTTVEmotes()
{ {
return _bttvEmotes; return _bttvEmotes;
} }
ConcurrentMap<QString, messages::LazyLoadedImage *> &EmoteManager::getFfzEmotes() ConcurrentMap<QString, messages::LazyLoadedImage *> &EmoteManager::getFFZEmotes()
{ {
return _ffzEmotes; return _ffzEmotes;
} }
@ -56,12 +128,12 @@ ConcurrentMap<QString, messages::LazyLoadedImage *> &EmoteManager::getChatterino
return _chatterinoEmotes; return _chatterinoEmotes;
} }
ConcurrentMap<QString, messages::LazyLoadedImage *> &EmoteManager::getBttvChannelEmoteFromCaches() ConcurrentMap<QString, messages::LazyLoadedImage *> &EmoteManager::getBTTVChannelEmoteFromCaches()
{ {
return _bttvChannelEmoteFromCaches; return _bttvChannelEmoteFromCaches;
} }
ConcurrentMap<int, messages::LazyLoadedImage *> &EmoteManager::getFfzChannelEmoteFromCaches() ConcurrentMap<int, messages::LazyLoadedImage *> &EmoteManager::getFFZChannelEmoteFromCaches()
{ {
return _ffzChannelEmoteFromCaches; return _ffzChannelEmoteFromCaches;
} }
@ -76,13 +148,7 @@ ConcurrentMap<QString, messages::LazyLoadedImage *> &EmoteManager::getMiscImageF
return _miscImageFromCache; return _miscImageFromCache;
} }
void EmoteManager::loadGlobalEmotes() void EmoteManager::loadBTTVEmotes()
{
loadBttvEmotes();
loadFfzEmotes();
}
void EmoteManager::loadBttvEmotes()
{ {
// bttv // bttv
QNetworkAccessManager *manager = new QNetworkAccessManager(); QNetworkAccessManager *manager = new QNetworkAccessManager();
@ -111,8 +177,9 @@ void EmoteManager::loadBttvEmotes()
tmp.detach(); tmp.detach();
QString url = tmp.replace("{{id}}", id).replace("{{image}}", "1x"); QString url = tmp.replace("{{id}}", id).replace("{{image}}", "1x");
EmoteManager::getBttvEmotes().insert( EmoteManager::getBTTVEmotes().insert(
code, new LazyLoadedImage(url, 1, code, code + "\nGlobal Bttv Emote")); code, new LazyLoadedImage(*this, this->windowManager, url, 1, code,
code + "\nGlobal BTTV Emote"));
} }
} }
@ -121,7 +188,7 @@ void EmoteManager::loadBttvEmotes()
}); });
} }
void EmoteManager::loadFfzEmotes() void EmoteManager::loadFFZEmotes()
{ {
// ffz // ffz
QNetworkAccessManager *manager = new QNetworkAccessManager(); QNetworkAccessManager *manager = new QNetworkAccessManager();
@ -153,8 +220,9 @@ void EmoteManager::loadFfzEmotes()
QJsonObject urls = object.value("urls").toObject(); QJsonObject urls = object.value("urls").toObject();
QString url1 = "http:" + urls.value("1").toString(); QString url1 = "http:" + urls.value("1").toString();
EmoteManager::getBttvEmotes().insert( EmoteManager::getBTTVEmotes().insert(
code, new LazyLoadedImage(url1, 1, code, code + "\nGlobal Ffz Emote")); code, new LazyLoadedImage(*this, this->windowManager, url1, 1, code,
code + "\nGlobal FFZ Emote"));
} }
} }
} }
@ -166,11 +234,12 @@ void EmoteManager::loadFfzEmotes()
LazyLoadedImage *EmoteManager::getTwitchEmoteById(const QString &name, long id) LazyLoadedImage *EmoteManager::getTwitchEmoteById(const QString &name, long id)
{ {
return EmoteManager::_twitchEmoteFromCache.getOrAdd(id, [&name, &id] { return EmoteManager::_twitchEmoteFromCache.getOrAdd(id, [this, &name, &id] {
qDebug() << "added twitch emote: " << id; qDebug() << "added twitch emote: " << id;
qreal scale; qreal scale;
QString url = getTwitchEmoteLink(id, scale); QString url = getTwitchEmoteLink(id, scale);
return new LazyLoadedImage(url, scale, name, name + "\nTwitch Emote"); return new LazyLoadedImage(*this, this->windowManager, url, scale, name,
name + "\nTwitch Emote");
}); });
} }
@ -188,24 +257,41 @@ QString EmoteManager::getTwitchEmoteLink(long id, qreal &scale)
LazyLoadedImage *EmoteManager::getCheerImage(long long amount, bool animated) LazyLoadedImage *EmoteManager::getCheerImage(long long amount, bool animated)
{ {
// TODO: fix this xD // TODO: fix this xD
return getCheerBadge(amount); return this->getCheerBadge(amount);
} }
LazyLoadedImage *EmoteManager::getCheerBadge(long long amount) LazyLoadedImage *EmoteManager::getCheerBadge(long long amount)
{ {
if (amount >= 100000) { if (amount >= 100000) {
return Resources::getCheerBadge100000(); return this->resources.cheerBadge100000;
} else if (amount >= 10000) { } else if (amount >= 10000) {
return Resources::getCheerBadge10000(); return this->resources.cheerBadge10000;
} else if (amount >= 5000) { } else if (amount >= 5000) {
return Resources::getCheerBadge5000(); return this->resources.cheerBadge5000;
} else if (amount >= 1000) { } else if (amount >= 1000) {
return Resources::getCheerBadge1000(); return this->resources.cheerBadge1000;
} else if (amount >= 100) { } else if (amount >= 100) {
return Resources::getCheerBadge100(); return this->resources.cheerBadge100;
} else { } else {
return Resources::getCheerBadge1(); return this->resources.cheerBadge1;
} }
} }
boost::signals2::signal<void()> &EmoteManager::getGifUpdateSignal()
{
if (!_gifUpdateTimerInitiated) {
_gifUpdateTimerInitiated = true;
_gifUpdateTimer.setInterval(30);
_gifUpdateTimer.start();
QObject::connect(&_gifUpdateTimer, &QTimer::timeout, [this] {
_gifUpdateTimerSignal();
this->windowManager.repaintGifEmotes();
});
}
return _gifUpdateTimerSignal;
}
} // namespace chatterino } // namespace chatterino

View file

@ -5,7 +5,6 @@
#include "concurrentmap.hpp" #include "concurrentmap.hpp"
#include "messages/lazyloadedimage.hpp" #include "messages/lazyloadedimage.hpp"
#include "twitch/emotevalue.hpp" #include "twitch/emotevalue.hpp"
#include "windowmanager.hpp"
#include <QMap> #include <QMap>
#include <QMutex> #include <QMutex>
@ -13,25 +12,33 @@
#include <boost/signals2.hpp> #include <boost/signals2.hpp>
namespace chatterino { namespace chatterino {
class WindowManager;
class Resources;
class EmoteManager class EmoteManager
{ {
public: public:
static EmoteManager &getInstance() using FFZEmoteMap = ConcurrentMap<QString, messages::LazyLoadedImage *>;
{ using BTTVEmoteMap = ConcurrentMap<QString, messages::LazyLoadedImage *>;
return instance; using ChatterinoEmoteMap = ConcurrentMap<QString, messages::LazyLoadedImage *>;
}
ConcurrentMap<QString, twitch::EmoteValue *> &getTwitchEmotes(); EmoteManager(WindowManager &_windowManager, Resources &_resources);
ConcurrentMap<QString, messages::LazyLoadedImage *> &getBttvEmotes();
ConcurrentMap<QString, messages::LazyLoadedImage *> &getFfzEmotes();
ConcurrentMap<QString, messages::LazyLoadedImage *> &getChatterinoEmotes();
ConcurrentMap<QString, messages::LazyLoadedImage *> &getBttvChannelEmoteFromCaches();
ConcurrentMap<int, messages::LazyLoadedImage *> &getFfzChannelEmoteFromCaches();
ConcurrentMap<long, messages::LazyLoadedImage *> &getTwitchEmoteFromCache();
ConcurrentMap<QString, messages::LazyLoadedImage *> &getMiscImageFromCache();
void loadGlobalEmotes(); void loadGlobalEmotes();
void reloadBTTVChannelEmotes(const QString &channelName, BTTVEmoteMap &channelEmoteMap);
void reloadFFZChannelEmotes(const QString &channelName, FFZEmoteMap &channelEmoteMap);
ConcurrentMap<QString, twitch::EmoteValue *> &getTwitchEmotes();
ConcurrentMap<QString, messages::LazyLoadedImage *> &getBTTVEmotes();
ConcurrentMap<QString, messages::LazyLoadedImage *> &getFFZEmotes();
ConcurrentMap<QString, messages::LazyLoadedImage *> &getChatterinoEmotes();
ConcurrentMap<QString, messages::LazyLoadedImage *> &getBTTVChannelEmoteFromCaches();
ConcurrentMap<int, messages::LazyLoadedImage *> &getFFZChannelEmoteFromCaches();
ConcurrentMap<long, messages::LazyLoadedImage *> &getTwitchEmoteFromCache();
ConcurrentMap<QString, messages::LazyLoadedImage *> &getMiscImageFromCache();
messages::LazyLoadedImage *getCheerImage(long long int amount, bool animated); messages::LazyLoadedImage *getCheerImage(long long int amount, bool animated);
messages::LazyLoadedImage *getCheerBadge(long long int amount); messages::LazyLoadedImage *getCheerBadge(long long int amount);
@ -47,29 +54,15 @@ public:
_generation++; _generation++;
} }
boost::signals2::signal<void()> &getGifUpdateSignal() boost::signals2::signal<void()> &getGifUpdateSignal();
{
if (!_gifUpdateTimerInitiated) {
_gifUpdateTimerInitiated = true;
_gifUpdateTimer.setInterval(30);
_gifUpdateTimer.start();
QObject::connect(&_gifUpdateTimer, &QTimer::timeout, [this] {
_gifUpdateTimerSignal();
WindowManager::getInstance().repaintGifEmotes();
});
}
return _gifUpdateTimerSignal;
}
private: private:
static EmoteManager instance; WindowManager &windowManager;
Resources &resources;
EmoteManager(); ConcurrentMap<QString, messages::LazyLoadedImage *> bttvChannelEmotes;
ConcurrentMap<QString, messages::LazyLoadedImage *> ffzChannelEmotes;
// variables
ConcurrentMap<QString, twitch::EmoteValue *> _twitchEmotes; ConcurrentMap<QString, twitch::EmoteValue *> _twitchEmotes;
ConcurrentMap<QString, messages::LazyLoadedImage *> _bttvEmotes; ConcurrentMap<QString, messages::LazyLoadedImage *> _bttvEmotes;
ConcurrentMap<QString, messages::LazyLoadedImage *> _ffzEmotes; ConcurrentMap<QString, messages::LazyLoadedImage *> _ffzEmotes;
@ -81,15 +74,15 @@ private:
boost::signals2::signal<void()> _gifUpdateTimerSignal; boost::signals2::signal<void()> _gifUpdateTimerSignal;
QTimer _gifUpdateTimer; QTimer _gifUpdateTimer;
bool _gifUpdateTimerInitiated; bool _gifUpdateTimerInitiated = false;
int _generation; int _generation = 0;
// methods // methods
static QString getTwitchEmoteLink(long id, qreal &scale); static QString getTwitchEmoteLink(long id, qreal &scale);
void loadFfzEmotes(); void loadFFZEmotes();
void loadBttvEmotes(); void loadBTTVEmotes();
}; };
} // namespace chatterino } // namespace chatterino

View file

@ -3,14 +3,15 @@
#include "asyncexec.hpp" #include "asyncexec.hpp"
#include "channel.hpp" #include "channel.hpp"
#include "channelmanager.hpp" #include "channelmanager.hpp"
#include "emotemanager.hpp"
#include "messages/messageparseargs.hpp" #include "messages/messageparseargs.hpp"
#include "twitch/twitchmessagebuilder.hpp" #include "twitch/twitchmessagebuilder.hpp"
#include "twitch/twitchparsemessage.hpp" #include "twitch/twitchparsemessage.hpp"
#include "twitch/twitchuser.hpp" #include "twitch/twitchuser.hpp"
#include "windowmanager.hpp"
#include <irccommand.h> #include <irccommand.h>
#include <ircconnection.h> #include <ircconnection.h>
#include <QJsonArray> #include <QJsonArray>
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonObject> #include <QJsonObject>
@ -23,12 +24,15 @@ using namespace chatterino::messages;
namespace chatterino { namespace chatterino {
IrcManager IrcManager::instance;
const QString IrcManager::defaultClientId("7ue61iz46fz11y3cugd0l3tawb4taal"); const QString IrcManager::defaultClientId("7ue61iz46fz11y3cugd0l3tawb4taal");
IrcManager::IrcManager() IrcManager::IrcManager(ChannelManager &_channelManager, Resources &_resources,
: _account(AccountManager::getInstance().getTwitchUser()) EmoteManager &_emoteManager, WindowManager &_windowManager)
: channelManager(_channelManager)
, resources(_resources)
, emoteManager(_emoteManager)
, windowManager(_windowManager)
, _account(AccountManager::getInstance().getTwitchUser())
{ {
} }
@ -168,7 +172,7 @@ void IrcManager::beginConnecting()
this->writeConnection->moveToThread(QCoreApplication::instance()->thread()); this->writeConnection->moveToThread(QCoreApplication::instance()->thread());
this->readConnection->moveToThread(QCoreApplication::instance()->thread()); this->readConnection->moveToThread(QCoreApplication::instance()->thread());
for (auto &channel : ChannelManager::getInstance().getItems()) { for (auto &channel : this->channelManager.getItems()) {
this->writeConnection->sendRaw("JOIN #" + channel->getName()); this->writeConnection->sendRaw("JOIN #" + channel->getName());
this->readConnection->sendRaw("JOIN #" + channel->getName()); this->readConnection->sendRaw("JOIN #" + channel->getName());
} }
@ -231,12 +235,14 @@ void IrcManager::partChannel(const QString &channelName)
void IrcManager::messageReceived(Communi::IrcMessage *message) void IrcManager::messageReceived(Communi::IrcMessage *message)
{ {
/*
qDebug() << "Message received: " << message->command(); qDebug() << "Message received: " << message->command();
// qInfo(message->command().toStdString().c_str()); // qInfo(message->command().toStdString().c_str());
// //
for (const auto &param : message->parameters()) { for (const auto &param : message->parameters()) {
qDebug() << "Param: " << param; qDebug() << "Param: " << param;
} }
*/
/* /*
const QString &command = message->command(); const QString &command = message->command();
@ -252,12 +258,13 @@ void IrcManager::messageReceived(Communi::IrcMessage *message)
void IrcManager::privateMessageReceived(Communi::IrcPrivateMessage *message) void IrcManager::privateMessageReceived(Communi::IrcPrivateMessage *message)
{ {
auto c = ChannelManager::getInstance().getChannel(message->target().mid(1)); auto c = this->channelManager.getChannel(message->target().mid(1));
if (c != nullptr) { if (c != nullptr) {
messages::MessageParseArgs args; messages::MessageParseArgs args;
c->addMessage(twitch::TwitchMessageBuilder::parse(message, c.get(), args)); c->addMessage(twitch::TwitchMessageBuilder::parse(message, c.get(), args, this->resources,
this->emoteManager, this->windowManager));
} }
} }

View file

@ -16,15 +16,18 @@
namespace chatterino { namespace chatterino {
class ChannelManager;
class Resources;
class EmoteManager;
class WindowManager;
class IrcManager : public QObject class IrcManager : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
static IrcManager &getInstance() IrcManager(ChannelManager &_channelManager, Resources &_resources, EmoteManager &_emoteManager,
{ WindowManager &_windowManager);
return instance;
}
static const QString defaultClientId; static const QString defaultClientId;
@ -48,8 +51,10 @@ public:
void setUser(const twitch::TwitchUser &account); void setUser(const twitch::TwitchUser &account);
private: private:
static IrcManager instance; ChannelManager &channelManager;
IrcManager(); Resources &resources;
EmoteManager &emoteManager;
WindowManager &windowManager;
// variables // variables
twitch::TwitchUser _account; twitch::TwitchUser _account;

View file

@ -1,3 +1,4 @@
#include "application.hpp"
#include "channelmanager.hpp" #include "channelmanager.hpp"
#include "colorscheme.hpp" #include "colorscheme.hpp"
#include "emojis.hpp" #include "emojis.hpp"
@ -16,9 +17,6 @@
#include <boost/signals2.hpp> #include <boost/signals2.hpp>
#include <pajlada/settings/settingmanager.hpp> #include <pajlada/settings/settingmanager.hpp>
using namespace chatterino;
using namespace chatterino::widgets;
namespace { namespace {
inline bool initSettings(bool portable) inline bool initSettings(bool portable)
@ -68,28 +66,25 @@ int main(int argc, char *argv[])
} }
chatterino::logging::init(); chatterino::logging::init();
SettingsManager::getInstance().load(); chatterino::SettingsManager::getInstance().load();
Resources::load(); chatterino::Emojis::loadEmojis();
Emojis::loadEmojis();
EmoteManager::getInstance().loadGlobalEmotes();
ColorScheme::getInstance().init(); int ret = 0;
WindowManager::getInstance().load(); {
// Initialize application
chatterino::Application app;
MainWindow &w = WindowManager::getInstance().getMainWindow(); // Start the application
w.show(); ret = app.run(a);
IrcManager::getInstance().connect(); // Application will go out of scope here and deinitialize itself
}
int ret = a.exec(); chatterino::SettingsManager::getInstance().save();
SettingsManager::getInstance().save();
// Save settings // Save settings
pajlada::Settings::SettingManager::save(); pajlada::Settings::SettingManager::save();
WindowManager::getInstance().save();
return ret; return ret;
} }

View file

@ -1,5 +1,4 @@
#include "messages/lazyloadedimage.hpp" #include "messages/lazyloadedimage.hpp"
#include "asyncexec.hpp" #include "asyncexec.hpp"
#include "emotemanager.hpp" #include "emotemanager.hpp"
#include "ircmanager.hpp" #include "ircmanager.hpp"
@ -18,15 +17,15 @@
namespace chatterino { namespace chatterino {
namespace messages { namespace messages {
LazyLoadedImage::LazyLoadedImage(const QString &url, qreal scale, const QString &name, LazyLoadedImage::LazyLoadedImage(EmoteManager &_emoteManager, WindowManager &_windowManager,
const QString &url, qreal scale, const QString &name,
const QString &tooltip, const QMargins &margin, bool isHat) const QString &tooltip, const QMargins &margin, bool isHat)
: _currentPixmap(nullptr) : emoteManager(_emoteManager)
, _currentFrame(0) , windowManager(_windowManager)
, _currentFrameOffset(0) , _currentPixmap(nullptr)
, _url(url) , _url(url)
, _name(name) , _name(name)
, _tooltip(tooltip) , _tooltip(tooltip)
, _animated(false)
, _margin(margin) , _margin(margin)
, _ishat(isHat) , _ishat(isHat)
, _scale(scale) , _scale(scale)
@ -34,14 +33,14 @@ LazyLoadedImage::LazyLoadedImage(const QString &url, qreal scale, const QString
{ {
} }
LazyLoadedImage::LazyLoadedImage(QPixmap *image, qreal scale, const QString &name, LazyLoadedImage::LazyLoadedImage(EmoteManager &_emoteManager, WindowManager &_windowManager,
QPixmap *image, qreal scale, const QString &name,
const QString &tooltip, const QMargins &margin, bool isHat) const QString &tooltip, const QMargins &margin, bool isHat)
: _currentPixmap(image) : emoteManager(_emoteManager)
, _currentFrame(0) , windowManager(_windowManager)
, _currentFrameOffset(0) , _currentPixmap(image)
, _name(name) , _name(name)
, _tooltip(tooltip) , _tooltip(tooltip)
, _animated(false)
, _margin(margin) , _margin(margin)
, _ishat(isHat) , _ishat(isHat)
, _scale(scale) , _scale(scale)
@ -81,11 +80,13 @@ void LazyLoadedImage::loadImage()
if (_allFrames.size() > 1) { if (_allFrames.size() > 1) {
_animated = true; _animated = true;
EmoteManager::getInstance().getGifUpdateSignal().connect([this] { gifUpdateTimout(); }); this->emoteManager.getGifUpdateSignal().connect([this] {
gifUpdateTimout(); //
});
} }
EmoteManager::getInstance().incGeneration(); this->emoteManager.incGeneration();
WindowManager::getInstance().layoutVisibleChatWidgets(); this->windowManager.layoutVisibleChatWidgets();
}); });
} }

View file

@ -4,15 +4,24 @@
#include <QString> #include <QString>
namespace chatterino { namespace chatterino {
class EmoteManager;
class WindowManager;
namespace messages { namespace messages {
class LazyLoadedImage : QObject class LazyLoadedImage : QObject
{ {
public: public:
explicit LazyLoadedImage(const QString &_url, qreal _scale = 1, const QString &_name = "", LazyLoadedImage() = delete;
explicit LazyLoadedImage(EmoteManager &_emoteManager, WindowManager &_windowManager,
const QString &_url, qreal _scale = 1, const QString &_name = "",
const QString &_tooltip = "", const QMargins &_margin = QMargins(), const QString &_tooltip = "", const QMargins &_margin = QMargins(),
bool isHat = false); bool isHat = false);
explicit LazyLoadedImage(QPixmap *_currentPixmap, qreal _scale = 1, const QString &_name = "",
explicit LazyLoadedImage(EmoteManager &_emoteManager, WindowManager &_windowManager,
QPixmap *_currentPixmap, qreal _scale = 1, const QString &_name = "",
const QString &_tooltip = "", const QMargins &_margin = QMargins(), const QString &_tooltip = "", const QMargins &_margin = QMargins(),
bool isHat = false); bool isHat = false);
@ -78,6 +87,9 @@ public:
} }
private: private:
EmoteManager &emoteManager;
WindowManager &windowManager;
struct FrameData { struct FrameData {
QPixmap *image; QPixmap *image;
int duration; int duration;
@ -85,13 +97,13 @@ private:
QPixmap *_currentPixmap; QPixmap *_currentPixmap;
std::vector<FrameData> _allFrames; std::vector<FrameData> _allFrames;
int _currentFrame; int _currentFrame = 0;
int _currentFrameOffset; int _currentFrameOffset = 0;
QString _url; QString _url;
QString _name; QString _name;
QString _tooltip; QString _tooltip;
bool _animated; bool _animated = false;
QMargins _margin; QMargins _margin;
bool _ishat; bool _ishat;
qreal _scale; qreal _scale;

View file

@ -21,16 +21,16 @@ namespace chatterino {
namespace messages { namespace messages {
Message::Message(const QString &text) Message::Message(const QString &text)
: _words() : _text(text)
, _text(text) , _words()
{ {
_words.push_back( _words.push_back(
Word(text, Word::Text, ColorScheme::getInstance().SystemMessageColor, text, QString())); Word(text, Word::Text, ColorScheme::getInstance().SystemMessageColor, text, QString()));
} }
Message::Message(const QString &text, const std::vector<Word> &words) Message::Message(const QString &text, const std::vector<Word> &words)
: _words(words) : _text(text)
, _text(text) , _words(words)
{ {
} }

View file

@ -23,8 +23,8 @@ typedef std::shared_ptr<Message> SharedMessage;
class Message class Message
{ {
public: public:
Message(const QString &text); explicit Message(const QString &text);
Message(const QString &text, const std::vector<messages::Word> &words); explicit Message(const QString &text, const std::vector<messages::Word> &words);
bool getCanHighlightTab() const; bool getCanHighlightTab() const;
const QString &getTimeoutUser() const; const QString &getTimeoutUser() const;

View file

@ -41,7 +41,11 @@ bool MessageRef::layout(int width, bool enableEmoteMargins)
int mediumTextLineHeight = int mediumTextLineHeight =
FontManager::getInstance().getFontMetrics(FontManager::Medium).height(); FontManager::getInstance().getFontMetrics(FontManager::Medium).height();
/* TODO(pajlada): Re-implement
bool recalculateImages = _emoteGeneration != EmoteManager::getInstance().getGeneration(); bool recalculateImages = _emoteGeneration != EmoteManager::getInstance().getGeneration();
*/
bool recalculateImages = true;
bool recalculateText = _fontGeneration != FontManager::getInstance().getGeneration(); bool recalculateText = _fontGeneration != FontManager::getInstance().getGeneration();
bool newWordTypes = _currentWordTypes != SettingsManager::getInstance().getWordTypeMask(); bool newWordTypes = _currentWordTypes != SettingsManager::getInstance().getWordTypeMask();
@ -53,7 +57,7 @@ bool MessageRef::layout(int width, bool enableEmoteMargins)
return false; return false;
} }
_emoteGeneration = EmoteManager::getInstance().getGeneration(); // _emoteGeneration = EmoteManager::getInstance().getGeneration();
_fontGeneration = FontManager::getInstance().getGeneration(); _fontGeneration = FontManager::getInstance().getGeneration();
for (auto &word : _message->getWords()) { for (auto &word : _message->getWords()) {

View file

@ -1,60 +1,39 @@
#include "resources.hpp" #include "resources.hpp"
#include "emotemanager.hpp"
#include "windowmanager.hpp"
#include <QPixmap> #include <QPixmap>
namespace chatterino { namespace chatterino {
messages::LazyLoadedImage *Resources::badgeStaff(nullptr); namespace {
messages::LazyLoadedImage *Resources::badgeAdmin(nullptr);
messages::LazyLoadedImage *Resources::badgeModerator(nullptr);
messages::LazyLoadedImage *Resources::badgeGlobalmod(nullptr);
messages::LazyLoadedImage *Resources::badgeTurbo(nullptr);
messages::LazyLoadedImage *Resources::badgeBroadcaster(nullptr);
messages::LazyLoadedImage *Resources::badgePremium(nullptr);
messages::LazyLoadedImage *Resources::cheerBadge100000(nullptr); inline messages::LazyLoadedImage *lli(EmoteManager &emoteManager, WindowManager &windowManager,
messages::LazyLoadedImage *Resources::cheerBadge10000(nullptr); const char *pixmapPath, qreal scale = 1)
messages::LazyLoadedImage *Resources::cheerBadge5000(nullptr);
messages::LazyLoadedImage *Resources::cheerBadge1000(nullptr);
messages::LazyLoadedImage *Resources::cheerBadge100(nullptr);
messages::LazyLoadedImage *Resources::cheerBadge1(nullptr);
messages::LazyLoadedImage *Resources::buttonBan(nullptr);
messages::LazyLoadedImage *Resources::buttonTimeout(nullptr);
Resources::Resources()
{ {
return new messages::LazyLoadedImage(emoteManager, windowManager, new QPixmap(pixmapPath),
scale);
} }
void Resources::load() } // namespace
Resources::Resources(EmoteManager &emoteManager, WindowManager &windowManager)
: badgeStaff(lli(emoteManager, windowManager, ":/images/staff_bg.png"))
, badgeAdmin(lli(emoteManager, windowManager, ":/images/admin_bg.png"))
, badgeGlobalModerator(lli(emoteManager, windowManager, ":/images/globalmod_bg.png"))
, badgeModerator(lli(emoteManager, windowManager, ":/images/moderator_bg.png"))
, badgeTurbo(lli(emoteManager, windowManager, ":/images/turbo_bg.png"))
, badgeBroadcaster(lli(emoteManager, windowManager, ":/images/broadcaster_bg.png"))
, badgePremium(lli(emoteManager, windowManager, ":/images/twitchprime_bg.png"))
, cheerBadge100000(lli(emoteManager, windowManager, ":/images/cheer100000"))
, cheerBadge10000(lli(emoteManager, windowManager, ":/images/cheer10000"))
, cheerBadge5000(lli(emoteManager, windowManager, ":/images/cheer5000"))
, cheerBadge1000(lli(emoteManager, windowManager, ":/images/cheer1000"))
, cheerBadge100(lli(emoteManager, windowManager, ":/images/cheer100"))
, cheerBadge1(lli(emoteManager, windowManager, ":/images/cheer1"))
, buttonBan(lli(emoteManager, windowManager, ":/images/button_ban.png", 0.25))
, buttonTimeout(lli(emoteManager, windowManager, ":/images/button_timeout.png", 0.25))
{ {
// badges
Resources::badgeStaff = new messages::LazyLoadedImage(new QPixmap(":/images/staff_bg.png"));
Resources::badgeAdmin = new messages::LazyLoadedImage(new QPixmap(":/images/admin_bg.png"));
Resources::badgeModerator =
new messages::LazyLoadedImage(new QPixmap(":/images/moderator_bg.png"));
Resources::badgeGlobalmod =
new messages::LazyLoadedImage(new QPixmap(":/images/globalmod_bg.png"));
Resources::badgeTurbo = new messages::LazyLoadedImage(new QPixmap(":/images/turbo_bg.png"));
Resources::badgeBroadcaster =
new messages::LazyLoadedImage(new QPixmap(":/images/broadcaster_bg.png"));
Resources::badgePremium =
new messages::LazyLoadedImage(new QPixmap(":/images/twitchprime_bg.png"));
// cheer badges
Resources::cheerBadge100000 =
new messages::LazyLoadedImage(new QPixmap(":/images/cheer100000"));
Resources::cheerBadge10000 = new messages::LazyLoadedImage(new QPixmap(":/images/cheer10000"));
Resources::cheerBadge5000 = new messages::LazyLoadedImage(new QPixmap(":/images/cheer5000"));
Resources::cheerBadge1000 = new messages::LazyLoadedImage(new QPixmap(":/images/cheer1000"));
Resources::cheerBadge100 = new messages::LazyLoadedImage(new QPixmap(":/images/cheer100"));
Resources::cheerBadge1 = new messages::LazyLoadedImage(new QPixmap(":/images/cheer1"));
// button
Resources::buttonBan =
new messages::LazyLoadedImage(new QPixmap(":/images/button_ban.png"), 0.25);
Resources::buttonTimeout =
new messages::LazyLoadedImage(new QPixmap(":/images/button_timeout.png"), 0.25);
} }
} // namespace chatterino } // namespace chatterino

View file

@ -4,108 +4,31 @@
namespace chatterino { namespace chatterino {
class EmoteManager;
class WindowManager;
class Resources class Resources
{ {
public: public:
static void load(); explicit Resources(EmoteManager &emoteManager, WindowManager &windowManager);
// badges messages::LazyLoadedImage *badgeStaff;
static messages::LazyLoadedImage *getBadgeStaff() messages::LazyLoadedImage *badgeAdmin;
{ messages::LazyLoadedImage *badgeGlobalModerator;
return badgeStaff; messages::LazyLoadedImage *badgeModerator;
} messages::LazyLoadedImage *badgeTurbo;
messages::LazyLoadedImage *badgeBroadcaster;
messages::LazyLoadedImage *badgePremium;
static messages::LazyLoadedImage *getBadgeAdmin() messages::LazyLoadedImage *cheerBadge100000;
{ messages::LazyLoadedImage *cheerBadge10000;
return badgeAdmin; messages::LazyLoadedImage *cheerBadge5000;
} messages::LazyLoadedImage *cheerBadge1000;
messages::LazyLoadedImage *cheerBadge100;
messages::LazyLoadedImage *cheerBadge1;
static messages::LazyLoadedImage *getBadgeGlobalmod() messages::LazyLoadedImage *buttonBan;
{ messages::LazyLoadedImage *buttonTimeout;
return badgeGlobalmod;
}
static messages::LazyLoadedImage *getBadgeModerator()
{
return badgeModerator;
}
static messages::LazyLoadedImage *getBadgeTurbo()
{
return badgeTurbo;
}
static messages::LazyLoadedImage *getBadgeBroadcaster()
{
return badgeBroadcaster;
}
static messages::LazyLoadedImage *getBadgePremium()
{
return badgePremium;
}
// cheer badges
static messages::LazyLoadedImage *getCheerBadge100000()
{
return cheerBadge100000;
}
static messages::LazyLoadedImage *getCheerBadge10000()
{
return cheerBadge10000;
}
static messages::LazyLoadedImage *getCheerBadge5000()
{
return cheerBadge5000;
}
static messages::LazyLoadedImage *getCheerBadge1000()
{
return cheerBadge1000;
}
static messages::LazyLoadedImage *getCheerBadge100()
{
return cheerBadge100;
}
static messages::LazyLoadedImage *getCheerBadge1()
{
return cheerBadge1;
}
static messages::LazyLoadedImage *getButtonBan()
{
return buttonBan;
}
static messages::LazyLoadedImage *getButtonTimeout()
{
return buttonTimeout;
}
private:
Resources();
static messages::LazyLoadedImage *badgeStaff;
static messages::LazyLoadedImage *badgeAdmin;
static messages::LazyLoadedImage *badgeGlobalmod;
static messages::LazyLoadedImage *badgeModerator;
static messages::LazyLoadedImage *badgeTurbo;
static messages::LazyLoadedImage *badgeBroadcaster;
static messages::LazyLoadedImage *badgePremium;
static messages::LazyLoadedImage *cheerBadge100000;
static messages::LazyLoadedImage *cheerBadge10000;
static messages::LazyLoadedImage *cheerBadge5000;
static messages::LazyLoadedImage *cheerBadge1000;
static messages::LazyLoadedImage *cheerBadge100;
static messages::LazyLoadedImage *cheerBadge1;
static messages::LazyLoadedImage *buttonBan;
static messages::LazyLoadedImage *buttonTimeout;
}; };
} // namespace chatterino } // namespace chatterino

View file

@ -34,6 +34,7 @@ private:
messages::Word::Type _wordTypeMask = messages::Word::Default; messages::Word::Type _wordTypeMask = messages::Word::Default;
// methods // methods
public: // temporary
void updateWordTypeMask(); void updateWordTypeMask();
public: public:

View file

@ -4,6 +4,7 @@
#include "emotemanager.hpp" #include "emotemanager.hpp"
#include "ircmanager.hpp" #include "ircmanager.hpp"
#include "resources.hpp" #include "resources.hpp"
#include "windowmanager.hpp"
using namespace chatterino::messages; using namespace chatterino::messages;
@ -17,45 +18,15 @@ TwitchMessageBuilder::TwitchMessageBuilder()
{ {
} }
void TwitchMessageBuilder::appendTwitchBadges(const QStringList &badges)
{
for (QString badge : badges) {
if (badge.startsWith("bits/")) {
long long int cheer = std::strtoll(badge.mid(5).toStdString().c_str(), nullptr, 10);
appendWord(Word(EmoteManager::getInstance().getCheerBadge(cheer), Word::BadgeCheer,
QString(), QString("Twitch Cheer" + QString::number(cheer))));
} else if (badge == "staff/1") {
appendWord(Word(Resources::getBadgeStaff(), Word::BadgeStaff, QString(),
QString("Twitch Staff")));
} else if (badge == "admin/1") {
appendWord(Word(Resources::getBadgeAdmin(), Word::BadgeAdmin, QString(),
QString("Twitch Admin")));
} else if (badge == "global_mod/1") {
appendWord(Word(Resources::getBadgeGlobalmod(), Word::BadgeGlobalMod, QString(),
QString("Global Moderator")));
} else if (badge == "moderator/1") {
// TODO: implement this xD
appendWord(Word(Resources::getBadgeTurbo(), Word::BadgeModerator, QString(),
QString("Channel Moderator"))); // custom badge
} else if (badge == "turbo/1") {
appendWord(Word(Resources::getBadgeStaff(), Word::BadgeTurbo, QString(),
QString("Turbo Subscriber")));
} else if (badge == "broadcaster/1") {
appendWord(Word(Resources::getBadgeBroadcaster(), Word::BadgeBroadcaster, QString(),
QString("Channel Broadcaster")));
} else if (badge == "premium/1") {
appendWord(Word(Resources::getBadgePremium(), Word::BadgePremium, QString(),
QString("Twitch Prime")));
}
}
}
SharedMessage TwitchMessageBuilder::parse(const Communi::IrcPrivateMessage *ircMessage, SharedMessage TwitchMessageBuilder::parse(const Communi::IrcPrivateMessage *ircMessage,
Channel *channel, const MessageParseArgs &args) Channel *channel, const MessageParseArgs &args,
const Resources &resources, EmoteManager &emoteManager,
WindowManager &windowManager)
{ {
TwitchMessageBuilder b; TwitchMessageBuilder b;
// timestamp // The timestamp is always appended to the builder
// Whether or not will be rendered is decided/checked later
b.appendTimestamp(); b.appendTimestamp();
auto tags = ircMessage->tags(); auto tags = ircMessage->tags();
@ -69,14 +40,7 @@ SharedMessage TwitchMessageBuilder::parse(const Communi::IrcPrivateMessage *ircM
// timestamps // timestamps
iterator = tags.find("tmi-sent-ts"); iterator = tags.find("tmi-sent-ts");
// mod buttons b.appendModerationWords(ircMessage, resources);
static QString buttonBanTooltip("Ban user");
static QString buttonTimeoutTooltip("Timeout user");
b.appendWord(Word(Resources::getButtonBan(), Word::ButtonBan, QString(), buttonBanTooltip,
Link(Link::UserBan, ircMessage->account())));
b.appendWord(Word(Resources::getButtonTimeout(), Word::ButtonTimeout, QString(),
buttonTimeoutTooltip, Link(Link::UserTimeout, ircMessage->account())));
// badges // badges
iterator = tags.find("badges"); iterator = tags.find("badges");
@ -84,7 +48,7 @@ SharedMessage TwitchMessageBuilder::parse(const Communi::IrcPrivateMessage *ircM
if (iterator != tags.end()) { if (iterator != tags.end()) {
auto badges = iterator.value().toString().split(','); auto badges = iterator.value().toString().split(',');
b.appendTwitchBadges(badges); b.appendTwitchBadges(badges, resources, emoteManager);
} }
// color // color
@ -124,11 +88,13 @@ SharedMessage TwitchMessageBuilder::parse(const Communi::IrcPrivateMessage *ircM
displayName + (hasLocalizedName ? (" (" + ircMessage->account() + ")") : QString()); displayName + (hasLocalizedName ? (" (" + ircMessage->account() + ")") : QString());
if (args.isSentWhisper) { if (args.isSentWhisper) {
userDisplayString += IrcManager::getInstance().getUser().getUserName(); // TODO(pajlada): Re-implement
// userDisplayString += IrcManager::getInstance().getUser().getUserName();
} }
if (args.isReceivedWhisper) { if (args.isReceivedWhisper) {
userDisplayString += " -> " + IrcManager::getInstance().getUser().getUserName(); // TODO(pajlada): Re-implement
// userDisplayString += " -> " + IrcManager::getInstance().getUser().getUserName();
} }
if (!ircMessage->isAction()) { if (!ircMessage->isAction()) {
@ -153,40 +119,11 @@ SharedMessage TwitchMessageBuilder::parse(const Communi::IrcPrivateMessage *ircM
std::vector<std::pair<long int, LazyLoadedImage *>> twitchEmotes; std::vector<std::pair<long int, LazyLoadedImage *>> twitchEmotes;
iterator = tags.find("emotes"); iterator = tags.find("emotes");
if (iterator != tags.end()) { if (iterator != tags.end()) {
auto emotes = iterator.value().toString().split('/'); QStringList emoteString = iterator.value().toString().split('/');
for (QString emote : emotes) { for (QString emote : emoteString) {
if (!emote.contains(':')) b.appendTwitchEmote(ircMessage, emote, twitchEmotes, emoteManager);
continue;
QStringList parameters = emote.split(':');
if (parameters.length() < 2)
continue;
long int id = std::stol(parameters.at(0).toStdString(), nullptr, 10);
QStringList occurences = parameters.at(1).split(',');
for (QString occurence : occurences) {
QStringList coords = occurence.split('-');
if (coords.length() < 2)
continue;
long int start = std::stol(coords.at(0).toStdString(), nullptr, 10);
long int end = std::stol(coords.at(1).toStdString(), nullptr, 10);
if (start >= end || start < 0 || end > ircMessage->content().length())
continue;
QString name = ircMessage->content().mid(start, end - start + 1);
twitchEmotes.push_back(std::pair<long int, LazyLoadedImage *>(
start, EmoteManager::getInstance().getTwitchEmoteById(name, id)));
}
} }
struct { struct {
@ -270,13 +207,15 @@ SharedMessage TwitchMessageBuilder::parse(const Communi::IrcPrivateMessage *ircM
QString bitsLink = QString bitsLink =
QString("http://static-cdn.jtvnw.net/bits/dark/static/" + color + "/1"); QString("http://static-cdn.jtvnw.net/bits/dark/static/" + color + "/1");
LazyLoadedImage *imageAnimated = LazyLoadedImage *imageAnimated = emoteManager.getMiscImageFromCache().getOrAdd(
EmoteManager::getInstance().getMiscImageFromCache().getOrAdd( bitsLinkAnimated, [&emoteManager, &windowManager, &bitsLinkAnimated] {
bitsLinkAnimated, return new LazyLoadedImage(emoteManager, windowManager,
[&bitsLinkAnimated] { return new LazyLoadedImage(bitsLinkAnimated); }); bitsLinkAnimated);
LazyLoadedImage *image = });
EmoteManager::getInstance().getMiscImageFromCache().getOrAdd( LazyLoadedImage *image = emoteManager.getMiscImageFromCache().getOrAdd(
bitsLink, [&bitsLink] { return new LazyLoadedImage(bitsLink); }); bitsLink, [&emoteManager, &windowManager, &bitsLink] {
return new LazyLoadedImage(emoteManager, windowManager, bitsLink);
});
b.appendWord(Word(imageAnimated, Word::BitsAnimated, QString("cheer"), b.appendWord(Word(imageAnimated, Word::BitsAnimated, QString("cheer"),
QString("Twitch Cheer"), QString("Twitch Cheer"),
@ -302,11 +241,11 @@ SharedMessage TwitchMessageBuilder::parse(const Communi::IrcPrivateMessage *ircM
LazyLoadedImage *bttvEmote; LazyLoadedImage *bttvEmote;
// TODO: Implement this (ignored emotes) // TODO: Implement this (ignored emotes)
if (EmoteManager::getInstance().getBttvEmotes().tryGet(string, bttvEmote) || if (emoteManager.getBTTVEmotes().tryGet(string, bttvEmote) ||
channel->getBttvChannelEmotes().tryGet(string, bttvEmote) || channel->getBttvChannelEmotes().tryGet(string, bttvEmote) ||
EmoteManager::getInstance().getFfzEmotes().tryGet(string, bttvEmote) || emoteManager.getFFZEmotes().tryGet(string, bttvEmote) ||
channel->getFfzChannelEmotes().tryGet(string, bttvEmote) || channel->getFfzChannelEmotes().tryGet(string, bttvEmote) ||
EmoteManager::getInstance().getChatterinoEmotes().tryGet(string, bttvEmote)) { emoteManager.getChatterinoEmotes().tryGet(string, bttvEmote)) {
b.appendWord(Word(bttvEmote, Word::BttvEmoteImage, bttvEmote->getName(), b.appendWord(Word(bttvEmote, Word::BttvEmoteImage, bttvEmote->getName(),
bttvEmote->getTooltip(), bttvEmote->getTooltip(),
Link(Link::Url, bttvEmote->getUrl()))); Link(Link::Url, bttvEmote->getUrl())));
@ -340,6 +279,92 @@ SharedMessage TwitchMessageBuilder::parse(const Communi::IrcPrivateMessage *ircM
return b.build(); return b.build();
} }
void TwitchMessageBuilder::appendModerationWords(const Communi::IrcPrivateMessage *ircMessage,
const Resources &resources)
{
// mod buttons
static QString buttonBanTooltip("Ban user");
static QString buttonTimeoutTooltip("Timeout user");
this->appendWord(Word(resources.buttonBan, Word::ButtonBan, QString(), buttonBanTooltip,
Link(Link::UserBan, ircMessage->account())));
this->appendWord(Word(resources.buttonTimeout, Word::ButtonTimeout, QString(),
buttonTimeoutTooltip, Link(Link::UserTimeout, ircMessage->account())));
}
void TwitchMessageBuilder::appendTwitchEmote(
const Communi::IrcPrivateMessage *ircMessage, const QString &emote,
std::vector<std::pair<long int, messages::LazyLoadedImage *>> &vec, EmoteManager &emoteManager)
{
if (!emote.contains(':')) {
return;
}
QStringList parameters = emote.split(':');
if (parameters.length() < 2) {
return;
}
long int id = std::stol(parameters.at(0).toStdString(), nullptr, 10);
QStringList occurences = parameters.at(1).split(',');
for (QString occurence : occurences) {
QStringList coords = occurence.split('-');
if (coords.length() < 2) {
return;
}
long int start = std::stol(coords.at(0).toStdString(), nullptr, 10);
long int end = std::stol(coords.at(1).toStdString(), nullptr, 10);
if (start >= end || start < 0 || end > ircMessage->content().length()) {
return;
}
QString name = ircMessage->content().mid(start, end - start + 1);
vec.push_back(std::pair<long int, LazyLoadedImage *>(
start, emoteManager.getTwitchEmoteById(name, id)));
}
}
void TwitchMessageBuilder::appendTwitchBadges(const QStringList &badges, const Resources &resources,
EmoteManager &emoteManager)
{
for (QString badge : badges) {
if (badge.startsWith("bits/")) {
long long int cheer = std::strtoll(badge.mid(5).toStdString().c_str(), nullptr, 10);
appendWord(Word(emoteManager.getCheerBadge(cheer), Word::BadgeCheer, QString(),
QString("Twitch Cheer" + QString::number(cheer))));
} else if (badge == "staff/1") {
appendWord(
Word(resources.badgeStaff, Word::BadgeStaff, QString(), QString("Twitch Staff")));
} else if (badge == "admin/1") {
appendWord(
Word(resources.badgeAdmin, Word::BadgeAdmin, QString(), QString("Twitch Admin")));
} else if (badge == "global_mod/1") {
appendWord(Word(resources.badgeGlobalModerator, Word::BadgeGlobalMod, QString(),
QString("Global Moderator")));
} else if (badge == "moderator/1") {
// TODO: implement this xD
appendWord(Word(resources.badgeTurbo, Word::BadgeModerator, QString(),
QString("Channel Moderator"))); // custom badge
} else if (badge == "turbo/1") {
appendWord(Word(resources.badgeStaff, Word::BadgeTurbo, QString(),
QString("Turbo Subscriber")));
} else if (badge == "broadcaster/1") {
appendWord(Word(resources.badgeBroadcaster, Word::BadgeBroadcaster, QString(),
QString("Channel Broadcaster")));
} else if (badge == "premium/1") {
appendWord(Word(resources.badgePremium, Word::BadgePremium, QString(),
QString("Twitch Prime")));
}
}
}
// bool // bool
// sortTwitchEmotes(const std::pair<long int, LazyLoadedImage *> &a, // sortTwitchEmotes(const std::pair<long int, LazyLoadedImage *> &a,
// const std::pair<long int, LazyLoadedImage *> &b) // const std::pair<long int, LazyLoadedImage *> &b)

View file

@ -4,8 +4,14 @@
#include "messages/messagebuilder.hpp" #include "messages/messagebuilder.hpp"
#include <QString> #include <QString>
#include <QVariant>
namespace chatterino { namespace chatterino {
class Resources;
class EmoteManager;
class WindowManager;
namespace twitch { namespace twitch {
class TwitchMessageBuilder : public messages::MessageBuilder class TwitchMessageBuilder : public messages::MessageBuilder
@ -13,17 +19,26 @@ class TwitchMessageBuilder : public messages::MessageBuilder
public: public:
TwitchMessageBuilder(); TwitchMessageBuilder();
void appendTwitchBadges(const QStringList &badges);
QString messageId; QString messageId;
QString userName; QString userName;
static messages::SharedMessage parse(const Communi::IrcPrivateMessage *ircMessage, static messages::SharedMessage parse(const Communi::IrcPrivateMessage *ircMessage,
Channel *channel, const messages::MessageParseArgs &args); Channel *channel, const messages::MessageParseArgs &args,
const Resources &resources, EmoteManager &emoteManager,
WindowManager &windowManager);
// static bool sortTwitchEmotes( // static bool sortTwitchEmotes(
// const std::pair<long int, messages::LazyLoadedImage *> &a, // const std::pair<long int, messages::LazyLoadedImage *> &a,
// const std::pair<long int, messages::LazyLoadedImage *> &b); // const std::pair<long int, messages::LazyLoadedImage *> &b);
private:
void appendModerationWords(const Communi::IrcPrivateMessage *ircMessage,
const Resources &resources);
void appendTwitchEmote(const Communi::IrcPrivateMessage *ircMessage, const QString &emote,
std::vector<std::pair<long int, messages::LazyLoadedImage *>> &vec,
EmoteManager &emoteManager);
void appendTwitchBadges(const QStringList &badges, const Resources &resources,
EmoteManager &emoteManager);
}; };
} // namespace twitch } // namespace twitch

View file

@ -30,9 +30,10 @@ inline void ezShortcut(ChatWidget *w, const char *key, T t)
} // namespace } // namespace
ChatWidget::ChatWidget(QWidget *parent) ChatWidget::ChatWidget(ChannelManager &_channelManager, QWidget *parent)
: QWidget(parent) : QWidget(parent)
, channel(ChannelManager::getInstance().getEmpty()) , channelManager(_channelManager)
, channel(_channelManager.getEmpty())
, vbox(this) , vbox(this)
, header(this) , header(this)
, view(this) , view(this)
@ -90,7 +91,7 @@ void ChatWidget::setChannelName(const QString &_newChannelName)
// remove current channel // remove current channel
if (!this->channelName.isEmpty()) { if (!this->channelName.isEmpty()) {
ChannelManager::getInstance().removeChannel(this->channelName); this->channelManager.removeChannel(this->channelName);
this->detachChannel(); this->detachChannel();
} }
@ -104,7 +105,7 @@ void ChatWidget::setChannelName(const QString &_newChannelName)
if (newChannelName.isEmpty()) { if (newChannelName.isEmpty()) {
this->channel = nullptr; this->channel = nullptr;
} else { } else {
this->setChannel(ChannelManager::getInstance().addChannel(newChannelName)); this->setChannel(this->channelManager.addChannel(newChannelName));
} }
// update header // update header
@ -240,7 +241,7 @@ void ChatWidget::doChangeChannel()
void ChatWidget::doPopup() void ChatWidget::doPopup()
{ {
// TODO: Copy signals and stuff too // TODO: Copy signals and stuff too
auto widget = new ChatWidget(); auto widget = new ChatWidget(this->channelManager);
widget->setChannelName(this->getChannelName()); widget->setChannelName(this->getChannelName());
widget->show(); widget->show();
} }

View file

@ -17,6 +17,9 @@
#include <boost/signals2/connection.hpp> #include <boost/signals2/connection.hpp>
namespace chatterino { namespace chatterino {
class ChannelManager;
namespace widgets { namespace widgets {
// Each ChatWidget consists of three sub-elements that handle their own part of the chat widget: // Each ChatWidget consists of three sub-elements that handle their own part of the chat widget:
@ -34,7 +37,7 @@ class ChatWidget : public QWidget
Q_OBJECT Q_OBJECT
public: public:
ChatWidget(QWidget *parent = nullptr); ChatWidget(ChannelManager &_channelManager, QWidget *parent = nullptr);
~ChatWidget(); ~ChatWidget();
std::shared_ptr<Channel> getChannel() const; std::shared_ptr<Channel> getChannel() const;
@ -53,6 +56,8 @@ protected:
void paintEvent(QPaintEvent *) override; void paintEvent(QPaintEvent *) override;
private: private:
ChannelManager &channelManager;
void setChannel(std::shared_ptr<Channel> newChannel); void setChannel(std::shared_ptr<Channel> newChannel);
void detachChannel(); void detachChannel();

View file

@ -1,4 +1,5 @@
#include "widgets/mainwindow.hpp" #include "widgets/mainwindow.hpp"
#include "channelmanager.hpp"
#include "colorscheme.hpp" #include "colorscheme.hpp"
#include "settingsmanager.hpp" #include "settingsmanager.hpp"
#include "widgets/chatwidget.hpp" #include "widgets/chatwidget.hpp"
@ -18,9 +19,10 @@
namespace chatterino { namespace chatterino {
namespace widgets { namespace widgets {
MainWindow::MainWindow(QWidget *parent) MainWindow::MainWindow(ChannelManager &_channelManager, QWidget *parent)
: QWidget(parent) : QWidget(parent)
, _notebook(this) , channelManager(_channelManager)
, notebook(this->channelManager, this)
, _loaded(false) , _loaded(false)
, _titleBar() , _titleBar()
{ {
@ -31,7 +33,7 @@ MainWindow::MainWindow(QWidget *parent)
// layout->addWidget(&_titleBar); // layout->addWidget(&_titleBar);
// } // }
layout->addWidget(&_notebook); layout->addWidget(&this->notebook);
setLayout(layout); setLayout(layout);
// set margin // set margin
@ -63,7 +65,7 @@ MainWindow::~MainWindow()
void MainWindow::layoutVisibleChatWidgets(Channel *channel) void MainWindow::layoutVisibleChatWidgets(Channel *channel)
{ {
auto *page = _notebook.getSelectedPage(); auto *page = this->notebook.getSelectedPage();
if (page == nullptr) { if (page == nullptr) {
return; return;
@ -82,7 +84,7 @@ void MainWindow::layoutVisibleChatWidgets(Channel *channel)
void MainWindow::repaintVisibleChatWidgets(Channel *channel) void MainWindow::repaintVisibleChatWidgets(Channel *channel)
{ {
auto *page = _notebook.getSelectedPage(); auto *page = this->notebook.getSelectedPage();
if (page == nullptr) { if (page == nullptr) {
return; return;
@ -101,7 +103,7 @@ void MainWindow::repaintVisibleChatWidgets(Channel *channel)
void MainWindow::repaintGifEmotes() void MainWindow::repaintGifEmotes()
{ {
auto *page = _notebook.getSelectedPage(); auto *page = this->notebook.getSelectedPage();
if (page == nullptr) { if (page == nullptr) {
return; return;
@ -118,7 +120,7 @@ void MainWindow::repaintGifEmotes()
void MainWindow::load(const boost::property_tree::ptree &tree) void MainWindow::load(const boost::property_tree::ptree &tree)
{ {
this->_notebook.load(tree); this->notebook.load(tree);
_loaded = true; _loaded = true;
} }
@ -129,14 +131,14 @@ boost::property_tree::ptree MainWindow::save()
child.put("type", "main"); child.put("type", "main");
_notebook.save(child); this->notebook.save(child);
return child; return child;
} }
void MainWindow::loadDefaults() void MainWindow::loadDefaults()
{ {
_notebook.loadDefaults(); this->notebook.loadDefaults();
_loaded = true; _loaded = true;
} }
@ -148,7 +150,7 @@ bool MainWindow::isLoaded() const
Notebook &MainWindow::getNotebook() Notebook &MainWindow::getNotebook()
{ {
return _notebook; return this->notebook;
} }
} // namespace widgets } // namespace widgets

View file

@ -11,6 +11,9 @@
#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/ptree.hpp>
namespace chatterino { namespace chatterino {
class ChannelManager;
namespace widgets { namespace widgets {
class MainWindow : public QWidget class MainWindow : public QWidget
@ -18,7 +21,7 @@ class MainWindow : public QWidget
Q_OBJECT Q_OBJECT
public: public:
explicit MainWindow(QWidget *parent = 0); explicit MainWindow(ChannelManager &_channelManager, QWidget *parent = nullptr);
~MainWindow(); ~MainWindow();
void layoutVisibleChatWidgets(Channel *channel = nullptr); void layoutVisibleChatWidgets(Channel *channel = nullptr);
@ -34,7 +37,9 @@ public:
Notebook &getNotebook(); Notebook &getNotebook();
private: private:
Notebook _notebook; ChannelManager &channelManager;
Notebook notebook;
bool _loaded; bool _loaded;
TitleBar _titleBar; TitleBar _titleBar;
}; };

View file

@ -18,8 +18,9 @@
namespace chatterino { namespace chatterino {
namespace widgets { namespace widgets {
Notebook::Notebook(QWidget *parent) Notebook::Notebook(ChannelManager &_channelManager, QWidget *parent)
: QWidget(parent) : QWidget(parent)
, channelManager(_channelManager)
, _addButton(this) , _addButton(this)
, _settingsButton(this) , _settingsButton(this)
, _userButton(this) , _userButton(this)
@ -47,7 +48,7 @@ Notebook::Notebook(QWidget *parent)
NotebookPage *Notebook::addPage(bool select) NotebookPage *Notebook::addPage(bool select)
{ {
auto tab = new NotebookTab(this); auto tab = new NotebookTab(this);
auto page = new NotebookPage(this, tab); auto page = new NotebookPage(this->channelManager, this, tab);
tab->show(); tab->show();

View file

@ -9,6 +9,9 @@
#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/ptree.hpp>
namespace chatterino { namespace chatterino {
class ChannelManager;
namespace widgets { namespace widgets {
class Notebook : public QWidget class Notebook : public QWidget
@ -18,7 +21,7 @@ class Notebook : public QWidget
public: public:
enum HighlightType { none, highlighted, newMessage }; enum HighlightType { none, highlighted, newMessage };
Notebook(QWidget *parent); Notebook(ChannelManager &_channelManager, QWidget *parent);
NotebookPage *addPage(bool select = false); NotebookPage *addPage(bool select = false);
@ -46,6 +49,8 @@ public slots:
void addPageButtonClicked(); void addPageButtonClicked();
private: private:
ChannelManager &channelManager;
QList<NotebookPage *> _pages; QList<NotebookPage *> _pages;
NotebookButton _addButton; NotebookButton _addButton;

View file

@ -19,9 +19,10 @@ bool NotebookPage::isDraggingSplit = false;
ChatWidget *NotebookPage::draggingSplit = nullptr; ChatWidget *NotebookPage::draggingSplit = nullptr;
std::pair<int, int> NotebookPage::dropPosition = std::pair<int, int>(-1, -1); std::pair<int, int> NotebookPage::dropPosition = std::pair<int, int>(-1, -1);
NotebookPage::NotebookPage(QWidget *parent, NotebookTab *tab) NotebookPage::NotebookPage(ChannelManager &_channelManager, QWidget *parent, NotebookTab *_tab)
: QWidget(parent) : QWidget(parent)
, _tab(tab) , channelManager(_channelManager)
, tab(_tab)
, _parentbox(this) , _parentbox(this)
, _chatWidgets() , _chatWidgets()
, _preview(this) , _preview(this)
@ -46,12 +47,12 @@ const std::vector<ChatWidget *> &NotebookPage::getChatWidgets() const
NotebookTab *NotebookPage::getTab() const NotebookTab *NotebookPage::getTab() const
{ {
return _tab; return this->tab;
} }
void NotebookPage::addChat(bool openChannelNameDialog) void NotebookPage::addChat(bool openChannelNameDialog)
{ {
ChatWidget *w = new ChatWidget(); ChatWidget *w = new ChatWidget(this->channelManager);
if (openChannelNameDialog) { if (openChannelNameDialog) {
w->showChangeChannelPopup(); w->showChangeChannelPopup();
@ -143,7 +144,7 @@ void NotebookPage::mouseReleaseEvent(QMouseEvent *event)
{ {
if (_hbox.count() == 0 && event->button() == Qt::LeftButton) { if (_hbox.count() == 0 && event->button() == Qt::LeftButton) {
// "Add Chat" was clicked // "Add Chat" was clicked
addToLayout(new ChatWidget(), std::pair<int, int>(-1, -1)); addToLayout(new ChatWidget(this->channelManager), std::pair<int, int>(-1, -1));
setCursor(QCursor(Qt::ArrowCursor)); setCursor(QCursor(Qt::ArrowCursor));
} }
@ -275,7 +276,7 @@ void NotebookPage::load(const boost::property_tree::ptree &tree)
for (const auto &v : tree.get_child("columns.")) { for (const auto &v : tree.get_child("columns.")) {
int row = 0; int row = 0;
for (const auto &innerV : v.second.get_child("")) { for (const auto &innerV : v.second.get_child("")) {
auto widget = new ChatWidget(); auto widget = new ChatWidget(this->channelManager);
widget->load(innerV.second); widget->load(innerV.second);
addToLayout(widget, std::pair<int, int>(column, row)); addToLayout(widget, std::pair<int, int>(column, row));
++row; ++row;

View file

@ -15,6 +15,9 @@
#include <boost/signals2.hpp> #include <boost/signals2.hpp>
namespace chatterino { namespace chatterino {
class ChannelManager;
namespace widgets { namespace widgets {
class NotebookPage : public QWidget class NotebookPage : public QWidget
@ -22,7 +25,7 @@ class NotebookPage : public QWidget
Q_OBJECT Q_OBJECT
public: public:
NotebookPage(QWidget *parent, NotebookTab *_tab); NotebookPage(ChannelManager &_channelManager, QWidget *parent, NotebookTab *_tab);
std::pair<int, int> removeFromLayout(ChatWidget *widget); std::pair<int, int> removeFromLayout(ChatWidget *widget);
void addToLayout(ChatWidget *widget, std::pair<int, int> position); void addToLayout(ChatWidget *widget, std::pair<int, int> position);
@ -49,6 +52,8 @@ protected:
void dropEvent(QDropEvent *event) override; void dropEvent(QDropEvent *event) override;
private: private:
ChannelManager &channelManager;
struct DropRegion { struct DropRegion {
QRect rect; QRect rect;
std::pair<int, int> position; std::pair<int, int> position;
@ -60,7 +65,7 @@ private:
} }
}; };
NotebookTab *_tab; NotebookTab *tab;
QVBoxLayout _parentbox; QVBoxLayout _parentbox;
QHBoxLayout _hbox; QHBoxLayout _hbox;

View file

@ -153,7 +153,9 @@ void SettingsDialog::addTabs()
QObject::connect(slider, &QSlider::valueChanged, this, [&settings](int value) { QObject::connect(slider, &QSlider::valueChanged, this, [&settings](int value) {
settings.themeHue.set(value / 1000.0); settings.themeHue.set(value / 1000.0);
WindowManager::getInstance().updateAll();
// TODO(pajlada): re-implement
// this->windowManager.updateAll();
}); });
group->setLayout(form); group->setLayout(form);

View file

@ -17,6 +17,7 @@
#include <pajlada/settings/setting.hpp> #include <pajlada/settings/setting.hpp>
namespace chatterino { namespace chatterino {
namespace widgets { namespace widgets {
class SettingsDialog : public QWidget class SettingsDialog : public QWidget

View file

@ -1,5 +1,6 @@
#include "windowmanager.hpp" #include "windowmanager.hpp"
#include "appdatapath.hpp" #include "appdatapath.hpp"
#include "channelmanager.hpp"
#include <QDebug> #include <QDebug>
#include <QStandardPaths> #include <QStandardPaths>
@ -7,10 +8,9 @@
#include <boost/property_tree/json_parser.hpp> #include <boost/property_tree/json_parser.hpp>
namespace chatterino { namespace chatterino {
WindowManager WindowManager::instance;
WindowManager::WindowManager() WindowManager::WindowManager(ChannelManager &_channelManager)
: _mainWindow(nullptr) : channelManager(_channelManager)
{ {
} }
@ -23,41 +23,41 @@ static const std::string &getSettingsPath()
void WindowManager::layoutVisibleChatWidgets(Channel *channel) void WindowManager::layoutVisibleChatWidgets(Channel *channel)
{ {
if (_mainWindow != nullptr) { if (this->mainWindow != nullptr) {
_mainWindow->layoutVisibleChatWidgets(channel); this->mainWindow->layoutVisibleChatWidgets(channel);
} }
} }
void WindowManager::repaintVisibleChatWidgets(Channel *channel) void WindowManager::repaintVisibleChatWidgets(Channel *channel)
{ {
if (_mainWindow != nullptr) { if (this->mainWindow != nullptr) {
_mainWindow->repaintVisibleChatWidgets(channel); this->mainWindow->repaintVisibleChatWidgets(channel);
} }
} }
void WindowManager::repaintGifEmotes() void WindowManager::repaintGifEmotes()
{ {
if (_mainWindow != nullptr) { if (this->mainWindow != nullptr) {
_mainWindow->repaintGifEmotes(); this->mainWindow->repaintGifEmotes();
} }
} }
void WindowManager::updateAll() void WindowManager::updateAll()
{ {
if (_mainWindow != nullptr) { if (this->mainWindow != nullptr) {
_mainWindow->update(); this->mainWindow->update();
} }
} }
widgets::MainWindow &WindowManager::getMainWindow() widgets::MainWindow &WindowManager::getMainWindow()
{ {
std::lock_guard<std::mutex> lock(_windowMutex); std::lock_guard<std::mutex> lock(this->windowMutex);
if (_mainWindow == nullptr) { if (this->mainWindow == nullptr) {
_mainWindow = new widgets::MainWindow(); this->mainWindow = new widgets::MainWindow(this->channelManager);
} }
return *_mainWindow; return *this->mainWindow;
} }
void WindowManager::load() void WindowManager::load()

View file

@ -6,13 +6,12 @@
namespace chatterino { namespace chatterino {
class ChannelManager;
class WindowManager class WindowManager
{ {
public: public:
static WindowManager &getInstance() explicit WindowManager(ChannelManager &_channelManager);
{
return instance;
}
void layoutVisibleChatWidgets(Channel *channel = nullptr); void layoutVisibleChatWidgets(Channel *channel = nullptr);
void repaintVisibleChatWidgets(Channel *channel = nullptr); void repaintVisibleChatWidgets(Channel *channel = nullptr);
@ -25,12 +24,12 @@ public:
void save(); void save();
private: private:
static WindowManager instance; ChannelManager &channelManager;
WindowManager(); std::mutex windowMutex;
std::mutex _windowMutex; // TODO(pajlada): Store as a value instead of a pointer
widgets::MainWindow *_mainWindow; widgets::MainWindow *mainWindow = nullptr;
}; };
} // namespace chatterino } // namespace chatterino