mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-21 22:24:07 +01:00
Refactor ConcurrentMap
* Add operator[] to ConcurrentMap which returns a TValue reference * BTTV/FFZ channel emotes are now stored in the Emote Manager, and each Channel object has a reference to their own BTTV/FFZ channel emote map. * Restructure EmoteManager a bit (simplify the ConcurrentMap havoc). * Add EmoteData struct which can store emote data (for now only messages::LazyLoadedImage*) * Add CompletionManager that does nothing
This commit is contained in:
parent
1f1b0d7f03
commit
5aa892e834
11 changed files with 239 additions and 139 deletions
|
@ -95,7 +95,8 @@ SOURCES += \
|
|||
src/widgets/accountpopup.cpp \
|
||||
src/messagefactory.cpp \
|
||||
src/widgets/basewidget.cpp \
|
||||
src/widgets/resizingtextedit.cpp
|
||||
src/widgets/resizingtextedit.cpp \
|
||||
src/completionmanager.cpp
|
||||
|
||||
HEADERS += \
|
||||
src/asyncexec.hpp \
|
||||
|
@ -155,7 +156,8 @@ HEADERS += \
|
|||
src/widgets/accountpopup.hpp \
|
||||
src/util/distancebetweenpoints.hpp \
|
||||
src/messagefactory.hpp \
|
||||
src/widgets/basewidget.hpp
|
||||
src/widgets/basewidget.hpp \
|
||||
src/completionmanager.hpp
|
||||
|
||||
PRECOMPILED_HEADER =
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "messagefactory.hpp"
|
||||
#include "resources.hpp"
|
||||
#include "windowmanager.hpp"
|
||||
#include "completionmanager.hpp"
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
|
@ -20,6 +21,7 @@ public:
|
|||
|
||||
int run(QApplication &qtApp);
|
||||
|
||||
CompletionManager completionManager;
|
||||
WindowManager windowManager;
|
||||
ColorScheme colorScheme;
|
||||
EmoteManager emoteManager;
|
||||
|
|
|
@ -26,6 +26,8 @@ Channel::Channel(WindowManager &_windowManager, EmoteManager &_emoteManager,
|
|||
, emoteManager(_emoteManager)
|
||||
, ircManager(_ircManager)
|
||||
, _name((channel.length() > 0 && channel[0] == '#') ? channel.mid(1) : channel)
|
||||
, bttvChannelEmotes(this->emoteManager.bttvChannels[channel])
|
||||
, ffzChannelEmotes(this->emoteManager.ffzChannels[channel])
|
||||
, _subLink("https://www.twitch.tv/" + _name + "/subscribe?ref=in_chat_subscriber_link")
|
||||
, _channelLink("https://twitch.tv/" + _name)
|
||||
, _popoutPlayerLink("https://player.twitch.tv/?channel=" + _name)
|
||||
|
@ -41,14 +43,14 @@ Channel::Channel(WindowManager &_windowManager, EmoteManager &_emoteManager,
|
|||
//
|
||||
// properties
|
||||
//
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> &Channel::getBttvChannelEmotes()
|
||||
EmoteManager::EmoteMap &Channel::getBTTVChannelEmotes()
|
||||
{
|
||||
return _bttvChannelEmotes;
|
||||
return this->bttvChannelEmotes;
|
||||
}
|
||||
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> &Channel::getFfzChannelEmotes()
|
||||
EmoteManager::EmoteMap &Channel::getFFZChannelEmotes()
|
||||
{
|
||||
return _ffzChannelEmotes;
|
||||
return this->ffzChannelEmotes;
|
||||
}
|
||||
|
||||
bool Channel::isEmpty() const
|
||||
|
@ -125,8 +127,8 @@ void Channel::addMessage(std::shared_ptr<Message> message)
|
|||
void Channel::reloadChannelEmotes()
|
||||
{
|
||||
printf("[Channel:%s] Reloading channel emotes\n", qPrintable(this->_name));
|
||||
this->emoteManager.reloadBTTVChannelEmotes(this->_name, this->_bttvChannelEmotes);
|
||||
this->emoteManager.reloadFFZChannelEmotes(this->_name, this->_ffzChannelEmotes);
|
||||
this->emoteManager.reloadBTTVChannelEmotes(this->_name);
|
||||
this->emoteManager.reloadFFZChannelEmotes(this->_name);
|
||||
}
|
||||
|
||||
void Channel::sendMessage(const QString &message)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "concurrentmap.hpp"
|
||||
#include "emotemanager.hpp"
|
||||
#include "logging/loggingchannel.hpp"
|
||||
#include "messages/lazyloadedimage.hpp"
|
||||
#include "messages/limitedqueue.hpp"
|
||||
|
@ -19,7 +20,6 @@ class Message;
|
|||
}
|
||||
|
||||
class WindowManager;
|
||||
class EmoteManager;
|
||||
class IrcManager;
|
||||
|
||||
class Channel
|
||||
|
@ -32,8 +32,8 @@ public:
|
|||
boost::signals2::signal<void(messages::SharedMessage &)> messageAppended;
|
||||
|
||||
// properties
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> &getBttvChannelEmotes();
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> &getFfzChannelEmotes();
|
||||
EmoteManager::EmoteMap &getBTTVChannelEmotes();
|
||||
EmoteManager::EmoteMap &getFFZChannelEmotes();
|
||||
|
||||
bool isEmpty() const;
|
||||
const QString &getName() const;
|
||||
|
@ -64,8 +64,8 @@ private:
|
|||
|
||||
QString _name;
|
||||
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> _bttvChannelEmotes;
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> _ffzChannelEmotes;
|
||||
EmoteManager::EmoteMap &bttvChannelEmotes;
|
||||
EmoteManager::EmoteMap &ffzChannelEmotes;
|
||||
|
||||
QString _subLink;
|
||||
QString _channelLink;
|
||||
|
|
20
src/completionmanager.cpp
Normal file
20
src/completionmanager.cpp
Normal file
|
@ -0,0 +1,20 @@
|
|||
#include "completionmanager.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
CompletionManager::CompletionManager()
|
||||
{
|
||||
}
|
||||
|
||||
CompletionModel *CompletionManager::createModel(const std::string &channelName)
|
||||
{
|
||||
CompletionModel *ret = new CompletionModel();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CompletionManager::updateModel(CompletionModel *model, const std::string &channelName)
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
51
src/completionmanager.hpp
Normal file
51
src/completionmanager.hpp
Normal file
|
@ -0,0 +1,51 @@
|
|||
#pragma once
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class CompletionModel : public QAbstractItemModel
|
||||
{
|
||||
public:
|
||||
virtual int columnCount(const QModelIndex & /*parent*/) const override
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual QVariant data(const QModelIndex &index, int role) const override
|
||||
{
|
||||
// TODO: Implement
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const override
|
||||
{
|
||||
// TODO: Implement
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
virtual QModelIndex parent(const QModelIndex &child) const override
|
||||
{
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
virtual int rowCount(const QModelIndex &parent) const override
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
class CompletionManager
|
||||
{
|
||||
CompletionManager();
|
||||
|
||||
public:
|
||||
CompletionModel *createModel(const std::string &channelName);
|
||||
void updateModel(CompletionModel *model, const std::string &channelName);
|
||||
|
||||
friend class Application;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
|
@ -14,16 +14,15 @@ class ConcurrentMap
|
|||
{
|
||||
public:
|
||||
ConcurrentMap()
|
||||
: _map()
|
||||
{
|
||||
}
|
||||
|
||||
bool tryGet(const TKey &name, TValue &value) const
|
||||
{
|
||||
QMutexLocker lock(&_mutex);
|
||||
QMutexLocker lock(&this->mutex);
|
||||
|
||||
auto a = _map.find(name);
|
||||
if (a == _map.end()) {
|
||||
auto a = this->data.find(name);
|
||||
if (a == this->data.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -34,35 +33,51 @@ public:
|
|||
|
||||
TValue getOrAdd(const TKey &name, std::function<TValue()> addLambda)
|
||||
{
|
||||
QMutexLocker lock(&_mutex);
|
||||
QMutexLocker lock(&this->mutex);
|
||||
|
||||
auto a = _map.find(name);
|
||||
if (a == _map.end()) {
|
||||
auto a = this->data.find(name);
|
||||
if (a == this->data.end()) {
|
||||
TValue value = addLambda();
|
||||
_map.insert(name, value);
|
||||
this->data.insert(name, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
return a.value();
|
||||
}
|
||||
|
||||
TValue &operator[](const TKey &name)
|
||||
{
|
||||
QMutexLocker lock(&this->mutex);
|
||||
|
||||
return this->data[name];
|
||||
}
|
||||
|
||||
ConcurrentMap(const ConcurrentMap &o)
|
||||
{
|
||||
}
|
||||
|
||||
ConcurrentMap &operator=(const ConcurrentMap &rhs)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
QMutexLocker lock(&_mutex);
|
||||
QMutexLocker lock(&this->mutex);
|
||||
|
||||
_map.clear();
|
||||
this->data.clear();
|
||||
}
|
||||
|
||||
void insert(const TKey &name, const TValue &value)
|
||||
{
|
||||
QMutexLocker lock(&_mutex);
|
||||
QMutexLocker lock(&this->mutex);
|
||||
|
||||
_map.insert(name, value);
|
||||
this->data.insert(name, value);
|
||||
}
|
||||
|
||||
private:
|
||||
mutable QMutex _mutex;
|
||||
QMap<TKey, TValue> _map;
|
||||
mutable QMutex mutex;
|
||||
QMap<TKey, TValue> data;
|
||||
};
|
||||
|
||||
template <typename TKey, typename TValue>
|
||||
|
@ -97,6 +112,13 @@ public:
|
|||
return a.value();
|
||||
}
|
||||
|
||||
TValue &operator[](const TKey &name)
|
||||
{
|
||||
QMutexLocker lock(&_mutex);
|
||||
|
||||
return this->_map[name];
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
QMutexLocker lock(&_mutex);
|
||||
|
|
|
@ -34,13 +34,14 @@ void EmoteManager::loadGlobalEmotes()
|
|||
this->loadFFZEmotes();
|
||||
}
|
||||
|
||||
void EmoteManager::reloadBTTVChannelEmotes(const QString &channelName,
|
||||
BTTVEmoteMap &channelEmoteMap)
|
||||
void EmoteManager::reloadBTTVChannelEmotes(const QString &channelName)
|
||||
{
|
||||
printf("[EmoteManager] Reload BTTV Channel Emotes for channel %s\n", qPrintable(channelName));
|
||||
|
||||
QString url("https://api.betterttv.net/2/channels/" + channelName);
|
||||
util::urlFetchJSON(url, [this, &channelEmoteMap](QJsonObject &rootNode) {
|
||||
util::urlFetchJSON(url, [this, channelName](QJsonObject &rootNode) {
|
||||
EmoteMap &channelEmoteMap = this->bttvChannels[channelName];
|
||||
|
||||
channelEmoteMap.clear();
|
||||
|
||||
auto emotesNode = rootNode.value("emotes").toArray();
|
||||
|
@ -60,8 +61,8 @@ void EmoteManager::reloadBTTVChannelEmotes(const QString &channelName,
|
|||
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");
|
||||
return EmoteData(new LazyLoadedImage(*this, this->windowManager, link, 1, code,
|
||||
code + "\nChannel BTTV Emote"));
|
||||
});
|
||||
|
||||
this->bttvChannelEmotes.insert(code, emote);
|
||||
|
@ -70,15 +71,15 @@ void EmoteManager::reloadBTTVChannelEmotes(const QString &channelName,
|
|||
});
|
||||
}
|
||||
|
||||
void EmoteManager::reloadFFZChannelEmotes(
|
||||
const QString &channelName,
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> &channelEmoteMap)
|
||||
void EmoteManager::reloadFFZChannelEmotes(const QString &channelName)
|
||||
{
|
||||
printf("[EmoteManager] Reload FFZ Channel Emotes for channel %s\n", qPrintable(channelName));
|
||||
|
||||
QString url("http://api.frankerfacez.com/v1/room/" + channelName);
|
||||
|
||||
util::urlFetchJSON(url, [this, &channelEmoteMap](QJsonObject &rootNode) {
|
||||
util::urlFetchJSON(url, [this, channelName](QJsonObject &rootNode) {
|
||||
EmoteMap &channelEmoteMap = this->ffzChannels[channelName];
|
||||
|
||||
channelEmoteMap.clear();
|
||||
|
||||
auto setsNode = rootNode.value("sets").toObject();
|
||||
|
@ -98,8 +99,8 @@ void EmoteManager::reloadFFZChannelEmotes(
|
|||
|
||||
auto emote =
|
||||
this->getFFZChannelEmoteFromCaches().getOrAdd(id, [this, &code, &url1] {
|
||||
return new LazyLoadedImage(*this, this->windowManager, url1, 1, code,
|
||||
code + "\nGlobal FFZ Emote");
|
||||
return EmoteData(new LazyLoadedImage(*this, this->windowManager, url1, 1,
|
||||
code, code + "\nGlobal FFZ Emote"));
|
||||
});
|
||||
|
||||
this->ffzChannelEmotes.insert(code, emote);
|
||||
|
@ -114,41 +115,36 @@ ConcurrentMap<QString, twitch::EmoteValue *> &EmoteManager::getTwitchEmotes()
|
|||
return _twitchEmotes;
|
||||
}
|
||||
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> &EmoteManager::getBTTVEmotes()
|
||||
EmoteManager::EmoteMap &EmoteManager::getBTTVEmotes()
|
||||
{
|
||||
return _bttvEmotes;
|
||||
}
|
||||
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> &EmoteManager::getFFZEmotes()
|
||||
EmoteManager::EmoteMap &EmoteManager::getFFZEmotes()
|
||||
{
|
||||
return _ffzEmotes;
|
||||
}
|
||||
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> &EmoteManager::getChatterinoEmotes()
|
||||
EmoteManager::EmoteMap &EmoteManager::getChatterinoEmotes()
|
||||
{
|
||||
return _chatterinoEmotes;
|
||||
}
|
||||
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> &EmoteManager::getBTTVChannelEmoteFromCaches()
|
||||
EmoteManager::EmoteMap &EmoteManager::getBTTVChannelEmoteFromCaches()
|
||||
{
|
||||
return _bttvChannelEmoteFromCaches;
|
||||
}
|
||||
|
||||
ConcurrentMap<int, messages::LazyLoadedImage *> &EmoteManager::getFFZChannelEmoteFromCaches()
|
||||
ConcurrentMap<int, EmoteData> &EmoteManager::getFFZChannelEmoteFromCaches()
|
||||
{
|
||||
return _ffzChannelEmoteFromCaches;
|
||||
}
|
||||
|
||||
ConcurrentMap<long, messages::LazyLoadedImage *> &EmoteManager::getTwitchEmoteFromCache()
|
||||
ConcurrentMap<long, EmoteData> &EmoteManager::getTwitchEmoteFromCache()
|
||||
{
|
||||
return _twitchEmoteFromCache;
|
||||
}
|
||||
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> &EmoteManager::getMiscImageFromCache()
|
||||
{
|
||||
return _miscImageFromCache;
|
||||
}
|
||||
|
||||
void EmoteManager::loadEmojis()
|
||||
{
|
||||
QFile file(":/emojidata.txt");
|
||||
|
@ -199,8 +195,8 @@ void EmoteManager::loadEmojis()
|
|||
}
|
||||
}
|
||||
|
||||
void EmoteManager::parseEmojis(
|
||||
std::vector<std::tuple<messages::LazyLoadedImage *, QString>> &parsedWords, const QString &text)
|
||||
void EmoteManager::parseEmojis(std::vector<std::tuple<EmoteData, QString>> &parsedWords,
|
||||
const QString &text)
|
||||
{
|
||||
int lastParsedEmojiEndIndex = 0;
|
||||
|
||||
|
@ -270,12 +266,11 @@ void EmoteManager::parseEmojis(
|
|||
|
||||
// Create or fetch cached emoji image
|
||||
auto emojiImage = this->emojiCache.getOrAdd(url, [this, &url] {
|
||||
return new LazyLoadedImage(*this, this->windowManager, url, 0.35); //
|
||||
return EmoteData(new LazyLoadedImage(*this, this->windowManager, url, 0.35)); //
|
||||
});
|
||||
|
||||
// Push the emoji as a word to parsedWords
|
||||
parsedWords.push_back(
|
||||
std::tuple<messages::LazyLoadedImage *, QString>(emojiImage, QString()));
|
||||
parsedWords.push_back(std::tuple<EmoteData, QString>(emojiImage, QString()));
|
||||
|
||||
lastParsedEmojiEndIndex = currentParsedEmojiEndIndex;
|
||||
|
||||
|
@ -373,14 +368,16 @@ void EmoteManager::loadFFZEmotes()
|
|||
});
|
||||
}
|
||||
|
||||
LazyLoadedImage *EmoteManager::getTwitchEmoteById(const QString &name, long id)
|
||||
// id is used for lookup
|
||||
// emoteName is used for giving a name to the emote in case it doesn't exist
|
||||
EmoteData EmoteManager::getTwitchEmoteById(long id, const QString &emoteName)
|
||||
{
|
||||
return EmoteManager::_twitchEmoteFromCache.getOrAdd(id, [this, &name, &id] {
|
||||
return _twitchEmoteFromCache.getOrAdd(id, [this, &emoteName, &id] {
|
||||
qDebug() << "added twitch emote: " << id;
|
||||
qreal scale;
|
||||
QString url = getTwitchEmoteLink(id, scale);
|
||||
return new LazyLoadedImage(*this, this->windowManager, url, scale, name,
|
||||
name + "\nTwitch Emote");
|
||||
return new LazyLoadedImage(*this, this->windowManager, url, scale, emoteName,
|
||||
emoteName + "\nTwitch Emote");
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -395,27 +392,10 @@ QString EmoteManager::getTwitchEmoteLink(long id, qreal &scale)
|
|||
return value.replace("{id}", QString::number(id)).replace("{scale}", "2");
|
||||
}
|
||||
|
||||
LazyLoadedImage *EmoteManager::getCheerImage(long long amount, bool animated)
|
||||
EmoteData EmoteManager::getCheerImage(long long amount, bool animated)
|
||||
{
|
||||
// TODO: fix this xD
|
||||
return this->getCheerBadge(amount);
|
||||
}
|
||||
|
||||
LazyLoadedImage *EmoteManager::getCheerBadge(long long amount)
|
||||
{
|
||||
if (amount >= 100000) {
|
||||
return this->resources.cheerBadge100000;
|
||||
} else if (amount >= 10000) {
|
||||
return this->resources.cheerBadge10000;
|
||||
} else if (amount >= 5000) {
|
||||
return this->resources.cheerBadge5000;
|
||||
} else if (amount >= 1000) {
|
||||
return this->resources.cheerBadge1000;
|
||||
} else if (amount >= 100) {
|
||||
return this->resources.cheerBadge100;
|
||||
} else {
|
||||
return this->resources.cheerBadge1;
|
||||
}
|
||||
return EmoteData();
|
||||
}
|
||||
|
||||
boost::signals2::signal<void()> &EmoteManager::getGifUpdateSignal()
|
||||
|
|
|
@ -18,33 +18,42 @@ namespace chatterino {
|
|||
class WindowManager;
|
||||
class Resources;
|
||||
|
||||
struct EmoteData {
|
||||
EmoteData()
|
||||
{
|
||||
}
|
||||
|
||||
EmoteData(messages::LazyLoadedImage *_image)
|
||||
: image(_image)
|
||||
{
|
||||
}
|
||||
|
||||
messages::LazyLoadedImage *image = nullptr;
|
||||
};
|
||||
|
||||
class EmoteManager
|
||||
{
|
||||
public:
|
||||
using FFZEmoteMap = ConcurrentMap<QString, messages::LazyLoadedImage *>;
|
||||
using BTTVEmoteMap = ConcurrentMap<QString, messages::LazyLoadedImage *>;
|
||||
using ChatterinoEmoteMap = ConcurrentMap<QString, messages::LazyLoadedImage *>;
|
||||
using EmoteMap = ConcurrentMap<QString, EmoteData>;
|
||||
|
||||
EmoteManager(WindowManager &_windowManager, Resources &_resources);
|
||||
|
||||
void loadGlobalEmotes();
|
||||
|
||||
void reloadBTTVChannelEmotes(const QString &channelName, BTTVEmoteMap &channelEmoteMap);
|
||||
void reloadFFZChannelEmotes(const QString &channelName, FFZEmoteMap &channelEmoteMap);
|
||||
void reloadBTTVChannelEmotes(const QString &channelName);
|
||||
void reloadFFZChannelEmotes(const QString &channelName);
|
||||
|
||||
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();
|
||||
EmoteMap &getBTTVEmotes();
|
||||
EmoteMap &getFFZEmotes();
|
||||
EmoteMap &getChatterinoEmotes();
|
||||
EmoteMap &getBTTVChannelEmoteFromCaches();
|
||||
ConcurrentMap<int, EmoteData> &getFFZChannelEmoteFromCaches();
|
||||
ConcurrentMap<long, EmoteData> &getTwitchEmoteFromCache();
|
||||
|
||||
messages::LazyLoadedImage *getCheerImage(long long int amount, bool animated);
|
||||
messages::LazyLoadedImage *getCheerBadge(long long int amount);
|
||||
EmoteData getCheerImage(long long int amount, bool animated);
|
||||
|
||||
messages::LazyLoadedImage *getTwitchEmoteById(const QString &name, long int id);
|
||||
EmoteData getTwitchEmoteById(long int id, const QString &emoteName);
|
||||
|
||||
int getGeneration()
|
||||
{
|
||||
|
@ -58,6 +67,9 @@ public:
|
|||
|
||||
boost::signals2::signal<void()> &getGifUpdateSignal();
|
||||
|
||||
// Bit badge/emotes?
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> miscImageCache;
|
||||
|
||||
private:
|
||||
WindowManager &windowManager;
|
||||
Resources &resources;
|
||||
|
@ -70,38 +82,44 @@ private:
|
|||
QMap<QChar, QVector<EmojiData>> emojiFirstByte;
|
||||
|
||||
// url Emoji-one image
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> emojiCache;
|
||||
EmoteMap emojiCache;
|
||||
|
||||
void loadEmojis();
|
||||
|
||||
public:
|
||||
void parseEmojis(std::vector<std::tuple<messages::LazyLoadedImage *, QString>> &parsedWords,
|
||||
const QString &text);
|
||||
void parseEmojis(std::vector<std::tuple<EmoteData, QString>> &parsedWords, const QString &text);
|
||||
|
||||
private:
|
||||
/// Twitch emotes
|
||||
ConcurrentMap<QString, twitch::EmoteValue *> _twitchEmotes;
|
||||
ConcurrentMap<long, messages::LazyLoadedImage *> _twitchEmoteFromCache;
|
||||
ConcurrentMap<long, EmoteData> _twitchEmoteFromCache;
|
||||
|
||||
/// BTTV emotes
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> bttvChannelEmotes;
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> _bttvEmotes;
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> _bttvChannelEmoteFromCaches;
|
||||
EmoteMap bttvChannelEmotes;
|
||||
|
||||
public:
|
||||
ConcurrentMap<QString, EmoteMap> bttvChannels;
|
||||
|
||||
private:
|
||||
EmoteMap _bttvEmotes;
|
||||
EmoteMap _bttvChannelEmoteFromCaches;
|
||||
|
||||
void loadBTTVEmotes();
|
||||
|
||||
/// FFZ emotes
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> ffzChannelEmotes;
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> _ffzEmotes;
|
||||
ConcurrentMap<int, messages::LazyLoadedImage *> _ffzChannelEmoteFromCaches;
|
||||
EmoteMap ffzChannelEmotes;
|
||||
|
||||
public:
|
||||
ConcurrentMap<QString, EmoteMap> ffzChannels;
|
||||
|
||||
private:
|
||||
EmoteMap _ffzEmotes;
|
||||
ConcurrentMap<int, EmoteData> _ffzChannelEmoteFromCaches;
|
||||
|
||||
void loadFFZEmotes();
|
||||
|
||||
/// Chatterino emotes
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> _chatterinoEmotes;
|
||||
|
||||
// ???
|
||||
ConcurrentMap<QString, messages::LazyLoadedImage *> _miscImageFromCache;
|
||||
EmoteMap _chatterinoEmotes;
|
||||
|
||||
boost::signals2::signal<void()> _gifUpdateTimerSignal;
|
||||
QTimer _gifUpdateTimer;
|
||||
|
|
|
@ -59,7 +59,7 @@ SharedMessage TwitchMessageBuilder::parse()
|
|||
}
|
||||
|
||||
// twitch emotes
|
||||
std::vector<std::pair<long int, LazyLoadedImage *>> twitchEmotes;
|
||||
std::vector<std::pair<long, EmoteData>> twitchEmotes;
|
||||
|
||||
iterator = this->tags.find("emotes");
|
||||
if (iterator != this->tags.end()) {
|
||||
|
@ -70,8 +70,8 @@ SharedMessage TwitchMessageBuilder::parse()
|
|||
}
|
||||
|
||||
struct {
|
||||
bool operator()(const std::pair<long int, messages::LazyLoadedImage *> &lhs,
|
||||
const std::pair<long int, messages::LazyLoadedImage *> &rhs)
|
||||
bool operator()(const std::pair<long, EmoteData> &lhs,
|
||||
const std::pair<long, EmoteData> &rhs)
|
||||
{
|
||||
return lhs.first < rhs.first;
|
||||
}
|
||||
|
@ -95,13 +95,13 @@ SharedMessage TwitchMessageBuilder::parse()
|
|||
// twitch emote
|
||||
if (currentTwitchEmote != twitchEmotes.end() && currentTwitchEmote->first == i) {
|
||||
this->appendWord(
|
||||
Word(currentTwitchEmote->second, Word::TwitchEmoteImage,
|
||||
currentTwitchEmote->second->getName(),
|
||||
currentTwitchEmote->second->getName() + QString("\nTwitch Emote")));
|
||||
Word(currentTwitchEmote->second.image, Word::TwitchEmoteImage,
|
||||
currentTwitchEmote->second.image->getName(),
|
||||
currentTwitchEmote->second.image->getName() + QString("\nTwitch Emote")));
|
||||
this->appendWord(
|
||||
Word(currentTwitchEmote->second->getName(), Word::TwitchEmoteText, textColor,
|
||||
currentTwitchEmote->second->getName(),
|
||||
currentTwitchEmote->second->getName() + QString("\nTwitch Emote")));
|
||||
Word(currentTwitchEmote->second.image->getName(), Word::TwitchEmoteText, textColor,
|
||||
currentTwitchEmote->second.image->getName(),
|
||||
currentTwitchEmote->second.image->getName() + QString("\nTwitch Emote")));
|
||||
|
||||
i += split.length() + 1;
|
||||
currentTwitchEmote = std::next(currentTwitchEmote);
|
||||
|
@ -110,15 +110,15 @@ SharedMessage TwitchMessageBuilder::parse()
|
|||
}
|
||||
|
||||
// split words
|
||||
std::vector<std::tuple<LazyLoadedImage *, QString>> parsed;
|
||||
std::vector<std::tuple<EmoteData, QString>> parsed;
|
||||
|
||||
// Parse emojis and take all non-emojis and put them in parsed as full text-words
|
||||
emoteManager.parseEmojis(parsed, split);
|
||||
|
||||
for (const std::tuple<LazyLoadedImage *, QString> &tuple : parsed) {
|
||||
LazyLoadedImage *image = std::get<0>(tuple);
|
||||
for (const auto &tuple : parsed) {
|
||||
const EmoteData &emoteData = std::get<0>(tuple);
|
||||
|
||||
if (image == nullptr) { // is text
|
||||
if (emoteData.image == nullptr) { // is text
|
||||
QString string = std::get<1>(tuple);
|
||||
|
||||
static QRegularExpression cheerRegex("cheer[1-9][0-9]*");
|
||||
|
@ -153,13 +153,13 @@ SharedMessage TwitchMessageBuilder::parse()
|
|||
QString bitsLink =
|
||||
QString("http://static-cdn.jtvnw.net/bits/dark/static/" + color + "/1");
|
||||
|
||||
LazyLoadedImage *imageAnimated = emoteManager.getMiscImageFromCache().getOrAdd(
|
||||
LazyLoadedImage *imageAnimated = emoteManager.miscImageCache.getOrAdd(
|
||||
bitsLinkAnimated, [this, &bitsLinkAnimated] {
|
||||
return new LazyLoadedImage(this->emoteManager, this->windowManager,
|
||||
bitsLinkAnimated);
|
||||
});
|
||||
LazyLoadedImage *image =
|
||||
emoteManager.getMiscImageFromCache().getOrAdd(bitsLink, [this, &bitsLink] {
|
||||
emoteManager.miscImageCache.getOrAdd(bitsLink, [this, &bitsLink] {
|
||||
return new LazyLoadedImage(this->emoteManager, this->windowManager,
|
||||
bitsLink);
|
||||
});
|
||||
|
@ -185,21 +185,21 @@ SharedMessage TwitchMessageBuilder::parse()
|
|||
}
|
||||
|
||||
// bttv / ffz emotes
|
||||
LazyLoadedImage *bttvEmote;
|
||||
EmoteData emoteData;
|
||||
|
||||
// TODO: Implement ignored emotes
|
||||
// Format of ignored emotes:
|
||||
// Emote name: "forsenPuke" - if string in ignoredEmotes
|
||||
// Will match emote regardless of source (i.e. bttv, ffz)
|
||||
// Emote source + name: "bttv:nyanPls"
|
||||
if (emoteManager.getBTTVEmotes().tryGet(string, bttvEmote) ||
|
||||
this->channel->getBttvChannelEmotes().tryGet(string, bttvEmote) ||
|
||||
emoteManager.getFFZEmotes().tryGet(string, bttvEmote) ||
|
||||
this->channel->getFfzChannelEmotes().tryGet(string, bttvEmote) ||
|
||||
emoteManager.getChatterinoEmotes().tryGet(string, bttvEmote)) {
|
||||
this->appendWord(Word(bttvEmote, Word::BttvEmoteImage, bttvEmote->getName(),
|
||||
bttvEmote->getTooltip(),
|
||||
Link(Link::Url, bttvEmote->getUrl())));
|
||||
if (emoteManager.getBTTVEmotes().tryGet(string, emoteData) ||
|
||||
this->channel->getBTTVChannelEmotes().tryGet(string, emoteData) ||
|
||||
emoteManager.getFFZEmotes().tryGet(string, emoteData) ||
|
||||
this->channel->getFFZChannelEmotes().tryGet(string, emoteData) ||
|
||||
emoteManager.getChatterinoEmotes().tryGet(string, emoteData)) {
|
||||
this->appendWord(Word(emoteData.image, Word::BttvEmoteImage,
|
||||
emoteData.image->getName(), emoteData.image->getTooltip(),
|
||||
Link(Link::Url, emoteData.image->getUrl())));
|
||||
|
||||
continue;
|
||||
}
|
||||
|
@ -212,8 +212,10 @@ SharedMessage TwitchMessageBuilder::parse()
|
|||
} else { // is emoji
|
||||
static QString emojiTooltip("Emoji");
|
||||
|
||||
this->appendWord(Word(image, Word::EmojiImage, image->getName(), emojiTooltip));
|
||||
Word(image->getName(), Word::EmojiText, textColor, image->getName(), emojiTooltip);
|
||||
this->appendWord(Word(emoteData.image, Word::EmojiImage, emoteData.image->getName(),
|
||||
emojiTooltip));
|
||||
Word(emoteData.image->getName(), Word::EmojiText, textColor,
|
||||
emoteData.image->getName(), emojiTooltip);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -316,9 +318,10 @@ void TwitchMessageBuilder::appendModerationButtons()
|
|||
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)
|
||||
void TwitchMessageBuilder::appendTwitchEmote(const Communi::IrcPrivateMessage *ircMessage,
|
||||
const QString &emote,
|
||||
std::vector<std::pair<long int, EmoteData>> &vec,
|
||||
EmoteManager &emoteManager)
|
||||
{
|
||||
if (!emote.contains(':')) {
|
||||
return;
|
||||
|
@ -350,8 +353,8 @@ void TwitchMessageBuilder::appendTwitchEmote(
|
|||
|
||||
QString name = ircMessage->content().mid(start, end - start + 1);
|
||||
|
||||
vec.push_back(std::pair<long int, LazyLoadedImage *>(
|
||||
start, emoteManager.getTwitchEmoteById(name, id)));
|
||||
vec.push_back(
|
||||
std::pair<long int, EmoteData>(start, emoteManager.getTwitchEmoteById(id, name)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "emotemanager.hpp"
|
||||
#include "messages/messagebuilder.hpp"
|
||||
#include "resources.hpp"
|
||||
|
||||
|
@ -8,7 +9,6 @@
|
|||
|
||||
namespace chatterino {
|
||||
|
||||
class EmoteManager;
|
||||
class WindowManager;
|
||||
class Channel;
|
||||
class ColorScheme;
|
||||
|
@ -55,7 +55,7 @@ private:
|
|||
|
||||
void appendModerationButtons();
|
||||
void appendTwitchEmote(const Communi::IrcPrivateMessage *ircMessage, const QString &emote,
|
||||
std::vector<std::pair<long int, messages::LazyLoadedImage *>> &vec,
|
||||
std::vector<std::pair<long, EmoteData>> &vec,
|
||||
EmoteManager &emoteManager);
|
||||
|
||||
void parseTwitchBadges();
|
||||
|
|
Loading…
Reference in a new issue