mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-21 22:24:07 +01:00
ChatWidgetView -> ChannelView, added Emote Picker
This commit is contained in:
parent
84c23a5d00
commit
c7b3480aaf
37 changed files with 532 additions and 407 deletions
|
@ -62,7 +62,6 @@ SOURCES += \
|
|||
src/widgets/chatwidgetheader.cpp \
|
||||
src/widgets/chatwidgetheaderbutton.cpp \
|
||||
src/widgets/chatwidgetinput.cpp \
|
||||
src/widgets/chatwidgetview.cpp \
|
||||
src/widgets/mainwindow.cpp \
|
||||
src/widgets/notebook.cpp \
|
||||
src/widgets/notebookbutton.cpp \
|
||||
|
@ -97,7 +96,9 @@ SOURCES += \
|
|||
src/completionmanager.cpp \
|
||||
src/widgets/logindialog.cpp \
|
||||
src/widgets/qualitypopup.cpp \
|
||||
src/widgets/emotepopup.cpp
|
||||
src/widgets/emotepopup.cpp \
|
||||
src/widgets/channelview.cpp \
|
||||
src/twitch/twitchchannel.cpp
|
||||
|
||||
HEADERS += \
|
||||
src/asyncexec.hpp \
|
||||
|
@ -118,7 +119,6 @@ HEADERS += \
|
|||
src/widgets/chatwidgetheader.hpp \
|
||||
src/widgets/chatwidgetheaderbutton.hpp \
|
||||
src/widgets/chatwidgetinput.hpp \
|
||||
src/widgets/chatwidgetview.hpp \
|
||||
src/widgets/mainwindow.hpp \
|
||||
src/widgets/notebook.hpp \
|
||||
src/widgets/notebookbutton.hpp \
|
||||
|
@ -159,7 +159,9 @@ HEADERS += \
|
|||
src/widgets/basewidget.hpp \
|
||||
src/completionmanager.hpp \
|
||||
src/widgets/qualitypopup.h \
|
||||
src/widgets/emotepopup.h
|
||||
src/widgets/emotepopup.h \
|
||||
src/widgets/channelview.hpp \
|
||||
src/twitch/twitchchannel.hpp
|
||||
|
||||
PRECOMPILED_HEADER =
|
||||
|
||||
|
|
|
@ -18,55 +18,14 @@ using namespace chatterino::messages;
|
|||
|
||||
namespace chatterino {
|
||||
|
||||
Channel::Channel(WindowManager &_windowManager, EmoteManager &_emoteManager,
|
||||
IrcManager &_ircManager, const QString &channelName, bool isSpecial)
|
||||
: windowManager(_windowManager)
|
||||
, emoteManager(_emoteManager)
|
||||
, ircManager(_ircManager)
|
||||
, name(channelName)
|
||||
, bttvChannelEmotes(this->emoteManager.bttvChannels[channelName])
|
||||
, ffzChannelEmotes(this->emoteManager.ffzChannels[channelName])
|
||||
, _subLink("https://www.twitch.tv/" + name + "/subscribe?ref=in_chat_subscriber_link")
|
||||
, _channelLink("https://twitch.tv/" + name)
|
||||
, _popoutPlayerLink("https://player.twitch.tv/?channel=" + name)
|
||||
, isLive(false)
|
||||
Channel::Channel()
|
||||
// , _loggingChannel(logging::get(_name))
|
||||
{
|
||||
qDebug() << "Open channel:" << this->name;
|
||||
|
||||
if (!isSpecial) {
|
||||
this->reloadChannelEmotes();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// properties
|
||||
//
|
||||
|
||||
bool Channel::isEmpty() const
|
||||
{
|
||||
return name.isEmpty();
|
||||
}
|
||||
|
||||
const QString &Channel::getSubLink() const
|
||||
{
|
||||
return _subLink;
|
||||
}
|
||||
|
||||
const QString &Channel::getChannelLink() const
|
||||
{
|
||||
return _channelLink;
|
||||
}
|
||||
|
||||
const QString &Channel::getPopoutPlayerLink() const
|
||||
{
|
||||
return _popoutPlayerLink;
|
||||
}
|
||||
|
||||
void Channel::setRoomID(std::string id)
|
||||
{
|
||||
this->roomID = id;
|
||||
this->roomIDchanged();
|
||||
return false;
|
||||
}
|
||||
|
||||
messages::LimitedQueueSnapshot<messages::SharedMessage> Channel::getMessageSnapshot()
|
||||
|
@ -74,9 +33,6 @@ messages::LimitedQueueSnapshot<messages::SharedMessage> Channel::getMessageSnaps
|
|||
return _messages.getSnapshot();
|
||||
}
|
||||
|
||||
//
|
||||
// methods
|
||||
//
|
||||
void Channel::addMessage(std::shared_ptr<Message> message)
|
||||
{
|
||||
std::shared_ptr<Message> deleted;
|
||||
|
@ -90,26 +46,15 @@ void Channel::addMessage(std::shared_ptr<Message> message)
|
|||
}
|
||||
|
||||
this->messageAppended(message);
|
||||
|
||||
this->windowManager.repaintVisibleChatWidgets(this);
|
||||
}
|
||||
|
||||
// private methods
|
||||
void Channel::reloadChannelEmotes()
|
||||
bool Channel::canSendMessage() const
|
||||
{
|
||||
printf("[Channel:%s] Reloading channel emotes\n", qPrintable(this->name));
|
||||
this->emoteManager.reloadBTTVChannelEmotes(this->name);
|
||||
this->emoteManager.reloadFFZChannelEmotes(this->name);
|
||||
return false;
|
||||
}
|
||||
|
||||
void Channel::sendMessage(const QString &message)
|
||||
{
|
||||
qDebug() << "Channel send message: " << message;
|
||||
|
||||
// Do last message processing
|
||||
QString parsedMessage = this->emoteManager.replaceShortCodes(message);
|
||||
|
||||
this->ircManager.sendMessage(name, parsedMessage);
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
|
|
|
@ -19,58 +19,30 @@ namespace messages {
|
|||
class Message;
|
||||
}
|
||||
|
||||
class WindowManager;
|
||||
class IrcManager;
|
||||
|
||||
class Channel
|
||||
{
|
||||
WindowManager &windowManager;
|
||||
EmoteManager &emoteManager;
|
||||
IrcManager &ircManager;
|
||||
|
||||
public:
|
||||
explicit Channel(WindowManager &_windowManager, EmoteManager &_emoteManager,
|
||||
IrcManager &_ircManager, const QString &channelName, bool isSpecial = false);
|
||||
explicit Channel();
|
||||
|
||||
boost::signals2::signal<void(messages::SharedMessage &)> messageRemovedFromStart;
|
||||
boost::signals2::signal<void(messages::SharedMessage &)> messageAppended;
|
||||
|
||||
bool isEmpty() const;
|
||||
const QString &getSubLink() const;
|
||||
const QString &getChannelLink() const;
|
||||
const QString &getPopoutPlayerLink() const;
|
||||
virtual bool isEmpty() const;
|
||||
messages::LimitedQueueSnapshot<messages::SharedMessage> getMessageSnapshot();
|
||||
|
||||
// methods
|
||||
void addMessage(messages::SharedMessage message);
|
||||
void reloadChannelEmotes();
|
||||
QString name;
|
||||
|
||||
void sendMessage(const QString &message);
|
||||
|
||||
std::string roomID;
|
||||
const QString name;
|
||||
bool isLive;
|
||||
QString streamViewerCount;
|
||||
QString streamStatus;
|
||||
QString streamGame;
|
||||
QString streamUptime;
|
||||
|
||||
void setRoomID(std::string id);
|
||||
boost::signals2::signal<void()> roomIDchanged;
|
||||
virtual bool canSendMessage() const;
|
||||
virtual void sendMessage(const QString &message);
|
||||
|
||||
private:
|
||||
// variables
|
||||
messages::LimitedQueue<messages::SharedMessage> _messages;
|
||||
|
||||
public:
|
||||
const EmoteManager::EmoteMap &bttvChannelEmotes;
|
||||
const EmoteManager::EmoteMap &ffzChannelEmotes;
|
||||
|
||||
private:
|
||||
QString _subLink;
|
||||
QString _channelLink;
|
||||
QString _popoutPlayerLink;
|
||||
|
||||
// std::shared_ptr<logging::Channel> _loggingChannel;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include "channelmanager.hpp"
|
||||
#include "ircmanager.hpp"
|
||||
|
||||
using namespace chatterino::twitch;
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
ChannelManager::ChannelManager(WindowManager &_windowManager, EmoteManager &_emoteManager,
|
||||
|
@ -8,9 +10,9 @@ ChannelManager::ChannelManager(WindowManager &_windowManager, EmoteManager &_emo
|
|||
: windowManager(_windowManager)
|
||||
, emoteManager(_emoteManager)
|
||||
, ircManager(_ircManager)
|
||||
, whispersChannel(new Channel(_windowManager, _emoteManager, _ircManager, "/whispers", true))
|
||||
, mentionsChannel(new Channel(_windowManager, _emoteManager, _ircManager, "/mentions", true))
|
||||
, emptyChannel(new Channel(_windowManager, _emoteManager, _ircManager, "", true))
|
||||
, whispersChannel(new TwitchChannel(_emoteManager, _ircManager, "/whispers", true))
|
||||
, mentionsChannel(new TwitchChannel(_emoteManager, _ircManager, "/mentions", true))
|
||||
, emptyChannel(new TwitchChannel(_emoteManager, _ircManager, "", true))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -20,19 +22,19 @@ const std::vector<std::shared_ptr<Channel>> ChannelManager::getItems()
|
|||
|
||||
std::vector<std::shared_ptr<Channel>> items;
|
||||
|
||||
for (auto &item : this->channels.values()) {
|
||||
for (auto &item : this->twitchChannels.values()) {
|
||||
items.push_back(std::get<0>(item));
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
std::shared_ptr<Channel> ChannelManager::addChannel(const QString &rawChannelName)
|
||||
std::shared_ptr<TwitchChannel> ChannelManager::addTwitchChannel(const QString &rawChannelName)
|
||||
{
|
||||
QString channelName = rawChannelName.toLower();
|
||||
|
||||
if (channelName.length() > 1 && channelName.at(0) == '/') {
|
||||
return this->getChannel(channelName);
|
||||
return this->getTwitchChannel(channelName);
|
||||
}
|
||||
|
||||
if (channelName.length() > 0 && channelName.at(0) == '#') {
|
||||
|
@ -41,12 +43,13 @@ std::shared_ptr<Channel> ChannelManager::addChannel(const QString &rawChannelNam
|
|||
|
||||
QMutexLocker locker(&this->channelsMutex);
|
||||
|
||||
auto it = this->channels.find(channelName);
|
||||
auto it = this->twitchChannels.find(channelName);
|
||||
|
||||
if (it == this->channels.end()) {
|
||||
auto channel = std::make_shared<Channel>(this->windowManager, this->emoteManager,
|
||||
this->ircManager, channelName);
|
||||
this->channels.insert(channelName, std::make_tuple(channel, 1));
|
||||
if (it == this->twitchChannels.end()) {
|
||||
auto channel =
|
||||
std::make_shared<TwitchChannel>(this->emoteManager, this->ircManager, channelName);
|
||||
|
||||
this->twitchChannels.insert(channelName, std::make_tuple(channel, 1));
|
||||
|
||||
this->ircManager.joinChannel(channelName);
|
||||
|
||||
|
@ -58,7 +61,7 @@ std::shared_ptr<Channel> ChannelManager::addChannel(const QString &rawChannelNam
|
|||
return std::get<0>(it.value());
|
||||
}
|
||||
|
||||
std::shared_ptr<Channel> ChannelManager::getChannel(const QString &channel)
|
||||
std::shared_ptr<TwitchChannel> ChannelManager::getTwitchChannel(const QString &channel)
|
||||
{
|
||||
QMutexLocker locker(&this->channelsMutex);
|
||||
|
||||
|
@ -76,16 +79,16 @@ std::shared_ptr<Channel> ChannelManager::getChannel(const QString &channel)
|
|||
return emptyChannel;
|
||||
}
|
||||
|
||||
auto a = this->channels.find(c);
|
||||
auto a = this->twitchChannels.find(c);
|
||||
|
||||
if (a == this->channels.end()) {
|
||||
if (a == this->twitchChannels.end()) {
|
||||
return emptyChannel;
|
||||
}
|
||||
|
||||
return std::get<0>(a.value());
|
||||
}
|
||||
|
||||
void ChannelManager::removeChannel(const QString &channel)
|
||||
void ChannelManager::removeTwitchChannel(const QString &channel)
|
||||
{
|
||||
QMutexLocker locker(&this->channelsMutex);
|
||||
|
||||
|
@ -95,9 +98,9 @@ void ChannelManager::removeChannel(const QString &channel)
|
|||
|
||||
QString c = channel.toLower();
|
||||
|
||||
auto a = this->channels.find(c);
|
||||
auto a = this->twitchChannels.find(c);
|
||||
|
||||
if (a == this->channels.end()) {
|
||||
if (a == this->twitchChannels.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -105,7 +108,7 @@ void ChannelManager::removeChannel(const QString &channel)
|
|||
|
||||
if (std::get<1>(a.value()) == 0) {
|
||||
this->ircManager.partChannel(c);
|
||||
this->channels.remove(c);
|
||||
this->twitchChannels.remove(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -123,4 +126,9 @@ const std::string &ChannelManager::getUserID(const std::string &username)
|
|||
return temporary;
|
||||
}
|
||||
|
||||
EmoteManager &ChannelManager::getEmoteManager()
|
||||
{
|
||||
return this->emoteManager;
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "channel.hpp"
|
||||
#include "channeldata.hpp"
|
||||
#include "twitch/twitchchannel.hpp"
|
||||
|
||||
#include <map>
|
||||
|
||||
|
@ -23,23 +24,24 @@ public:
|
|||
|
||||
const std::vector<std::shared_ptr<Channel>> getItems();
|
||||
|
||||
std::shared_ptr<Channel> addChannel(const QString &channel);
|
||||
std::shared_ptr<Channel> getChannel(const QString &channel);
|
||||
void removeChannel(const QString &channel);
|
||||
std::shared_ptr<twitch::TwitchChannel> addTwitchChannel(const QString &channel);
|
||||
std::shared_ptr<twitch::TwitchChannel> getTwitchChannel(const QString &channel);
|
||||
void removeTwitchChannel(const QString &channel);
|
||||
|
||||
const std::string &getUserID(const std::string &username);
|
||||
EmoteManager &getEmoteManager();
|
||||
|
||||
// Special channels
|
||||
const std::shared_ptr<Channel> whispersChannel;
|
||||
const std::shared_ptr<Channel> mentionsChannel;
|
||||
const std::shared_ptr<Channel> emptyChannel;
|
||||
const std::shared_ptr<twitch::TwitchChannel> whispersChannel;
|
||||
const std::shared_ptr<twitch::TwitchChannel> mentionsChannel;
|
||||
const std::shared_ptr<twitch::TwitchChannel> emptyChannel;
|
||||
|
||||
private:
|
||||
std::map<std::string, std::string> usernameToID;
|
||||
std::map<std::string, ChannelData> channelDatas;
|
||||
|
||||
QMutex channelsMutex;
|
||||
QMap<QString, std::tuple<std::shared_ptr<Channel>, int>> channels;
|
||||
QMap<QString, std::tuple<std::shared_ptr<twitch::TwitchChannel>, int>> twitchChannels;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
|
|
|
@ -20,7 +20,7 @@ public:
|
|||
|
||||
bool tryGet(const TKey &name, TValue &value) const
|
||||
{
|
||||
QMutexLocker lock(this->mutex.get());
|
||||
QMutexLocker lock(&this->mutex);
|
||||
|
||||
auto a = this->data.find(name);
|
||||
if (a == this->data.end()) {
|
||||
|
@ -34,7 +34,7 @@ public:
|
|||
|
||||
TValue getOrAdd(const TKey &name, std::function<TValue()> addLambda)
|
||||
{
|
||||
QMutexLocker lock(this->mutex.get());
|
||||
QMutexLocker lock(&this->mutex);
|
||||
|
||||
auto a = this->data.find(name);
|
||||
if (a == this->data.end()) {
|
||||
|
@ -48,42 +48,28 @@ public:
|
|||
|
||||
TValue &operator[](const TKey &name)
|
||||
{
|
||||
QMutexLocker lock(this->mutex.get());
|
||||
QMutexLocker lock(&this->mutex);
|
||||
|
||||
return this->data[name];
|
||||
}
|
||||
|
||||
ConcurrentMap(const ConcurrentMap &o)
|
||||
: mutex(std::move(o.mutex))
|
||||
, data(std::move(o.data))
|
||||
{
|
||||
}
|
||||
|
||||
ConcurrentMap &operator=(const ConcurrentMap &rhs)
|
||||
{
|
||||
this->mutex = std::move(rhs.mutex);
|
||||
this->data = std::move(rhs.data);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
QMutexLocker lock(this->mutex.get());
|
||||
QMutexLocker lock(&this->mutex);
|
||||
|
||||
this->data.clear();
|
||||
}
|
||||
|
||||
void insert(const TKey &name, const TValue &value)
|
||||
{
|
||||
QMutexLocker lock(this->mutex.get());
|
||||
QMutexLocker lock(&this->mutex);
|
||||
|
||||
this->data.insert(name, value);
|
||||
}
|
||||
|
||||
void each(std::function<void(const TKey &name, const TValue &value)> &func) const
|
||||
void each(std::function<void(const TKey &name, const TValue &value)> func) const
|
||||
{
|
||||
QMutexLocker lock(this->mutex.get());
|
||||
QMutexLocker lock(&this->mutex);
|
||||
|
||||
QMapIterator<TKey, TValue> it(this->data);
|
||||
|
||||
|
@ -94,66 +80,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
mutable std::unique_ptr<QMutex> mutex;
|
||||
mutable QMutex mutex;
|
||||
QMap<TKey, TValue> data;
|
||||
};
|
||||
|
||||
template <typename TKey, typename TValue>
|
||||
class ConcurrentStdMap
|
||||
{
|
||||
public:
|
||||
bool tryGet(const TKey &name, TValue &value) const
|
||||
{
|
||||
QMutexLocker lock(&_mutex);
|
||||
|
||||
auto a = _map.find(name);
|
||||
if (a == _map.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
value = a.value();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TValue getOrAdd(const TKey &name, std::function<TValue()> addLambda)
|
||||
{
|
||||
QMutexLocker lock(&_mutex);
|
||||
|
||||
auto a = _map.find(name);
|
||||
if (a == _map.end()) {
|
||||
TValue value = addLambda();
|
||||
_map.insert(name, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
return a.value();
|
||||
}
|
||||
|
||||
TValue &operator[](const TKey &name)
|
||||
{
|
||||
QMutexLocker lock(&_mutex);
|
||||
|
||||
return this->_map[name];
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
QMutexLocker lock(&_mutex);
|
||||
|
||||
_map.clear();
|
||||
}
|
||||
|
||||
void insert(const TKey &name, const TValue &value)
|
||||
{
|
||||
QMutexLocker lock(&_mutex);
|
||||
|
||||
_map.insert(name, value);
|
||||
}
|
||||
|
||||
private:
|
||||
mutable QMutex _mutex;
|
||||
std::map<TKey, TValue> _map;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
|
|
|
@ -39,15 +39,19 @@ void EmoteManager::loadGlobalEmotes()
|
|||
this->loadFFZEmotes();
|
||||
}
|
||||
|
||||
void EmoteManager::reloadBTTVChannelEmotes(const QString &channelName)
|
||||
void EmoteManager::reloadBTTVChannelEmotes(const QString &channelName, std::weak_ptr<EmoteMap> _map)
|
||||
{
|
||||
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, channelName](QJsonObject &rootNode) {
|
||||
EmoteMap &channelEmoteMap = this->bttvChannels[channelName];
|
||||
util::urlFetchJSON(url, [this, channelName, _map](QJsonObject &rootNode) {
|
||||
auto map = _map.lock();
|
||||
|
||||
channelEmoteMap.clear();
|
||||
if (_map.expired()) {
|
||||
return;
|
||||
}
|
||||
|
||||
map->clear();
|
||||
|
||||
auto emotesNode = rootNode.value("emotes").toArray();
|
||||
|
||||
|
@ -72,7 +76,7 @@ void EmoteManager::reloadBTTVChannelEmotes(const QString &channelName)
|
|||
});
|
||||
|
||||
this->bttvChannelEmotes.insert(code, emote);
|
||||
channelEmoteMap.insert(code, emote);
|
||||
map->insert(code, emote);
|
||||
codes.push_back(code.toStdString());
|
||||
}
|
||||
|
||||
|
@ -80,16 +84,20 @@ void EmoteManager::reloadBTTVChannelEmotes(const QString &channelName)
|
|||
});
|
||||
}
|
||||
|
||||
void EmoteManager::reloadFFZChannelEmotes(const QString &channelName)
|
||||
void EmoteManager::reloadFFZChannelEmotes(const QString &channelName, std::weak_ptr<EmoteMap> _map)
|
||||
{
|
||||
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, channelName](QJsonObject &rootNode) {
|
||||
EmoteMap &channelEmoteMap = this->ffzChannels[channelName];
|
||||
util::urlFetchJSON(url, [this, channelName, _map](QJsonObject &rootNode) {
|
||||
auto map = _map.lock();
|
||||
|
||||
channelEmoteMap.clear();
|
||||
if (_map.expired()) {
|
||||
return;
|
||||
}
|
||||
|
||||
map->clear();
|
||||
|
||||
auto setsNode = rootNode.value("sets").toObject();
|
||||
|
||||
|
@ -114,7 +122,7 @@ void EmoteManager::reloadFFZChannelEmotes(const QString &channelName)
|
|||
});
|
||||
|
||||
this->ffzChannelEmotes.insert(code, emote);
|
||||
channelEmoteMap.insert(code, emote);
|
||||
map->insert(code, emote);
|
||||
codes.push_back(code.toStdString());
|
||||
}
|
||||
|
||||
|
@ -128,17 +136,17 @@ ConcurrentMap<QString, twitch::EmoteValue *> &EmoteManager::getTwitchEmotes()
|
|||
return _twitchEmotes;
|
||||
}
|
||||
|
||||
EmoteManager::EmoteMap &EmoteManager::getFFZEmotes()
|
||||
EmoteMap &EmoteManager::getFFZEmotes()
|
||||
{
|
||||
return ffzGlobalEmotes;
|
||||
}
|
||||
|
||||
EmoteManager::EmoteMap &EmoteManager::getChatterinoEmotes()
|
||||
EmoteMap &EmoteManager::getChatterinoEmotes()
|
||||
{
|
||||
return _chatterinoEmotes;
|
||||
}
|
||||
|
||||
EmoteManager::EmoteMap &EmoteManager::getBTTVChannelEmoteFromCaches()
|
||||
EmoteMap &EmoteManager::getBTTVChannelEmoteFromCaches()
|
||||
{
|
||||
return _bttvChannelEmoteFromCaches;
|
||||
}
|
||||
|
|
|
@ -32,17 +32,19 @@ struct EmoteData {
|
|||
messages::LazyLoadedImage *image = nullptr;
|
||||
};
|
||||
|
||||
typedef ConcurrentMap<QString, EmoteData> EmoteMap;
|
||||
|
||||
class EmoteManager
|
||||
{
|
||||
public:
|
||||
using EmoteMap = ConcurrentMap<QString, EmoteData>;
|
||||
|
||||
explicit EmoteManager(WindowManager &_windowManager);
|
||||
|
||||
void loadGlobalEmotes();
|
||||
|
||||
void reloadBTTVChannelEmotes(const QString &channelName);
|
||||
void reloadFFZChannelEmotes(const QString &channelName);
|
||||
void reloadBTTVChannelEmotes(const QString &channelName,
|
||||
std::weak_ptr<EmoteMap> channelEmoteMap);
|
||||
void reloadFFZChannelEmotes(const QString &channelName,
|
||||
std::weak_ptr<EmoteMap> channelEmoteMap);
|
||||
|
||||
ConcurrentMap<QString, twitch::EmoteValue *> &getTwitchEmotes();
|
||||
EmoteMap &getFFZEmotes();
|
||||
|
|
|
@ -237,7 +237,7 @@ void IrcManager::partChannel(const QString &channelName)
|
|||
void IrcManager::privateMessageReceived(Communi::IrcPrivateMessage *message)
|
||||
{
|
||||
this->onPrivateMessage.invoke(message);
|
||||
auto c = this->channelManager.getChannel(message->target().mid(1));
|
||||
auto c = this->channelManager.getTwitchChannel(message->target().mid(1));
|
||||
|
||||
if (!c) {
|
||||
return;
|
||||
|
@ -283,7 +283,7 @@ void IrcManager::handleRoomStateMessage(Communi::IrcMessage *message)
|
|||
std::string roomID = iterator.value().toString().toStdString();
|
||||
|
||||
auto channel = QString(message->toData()).split("#").at(1);
|
||||
channelManager.getChannel(channel)->setRoomID(roomID);
|
||||
channelManager.getTwitchChannel(channel)->setRoomID(roomID);
|
||||
|
||||
this->resources.loadChannelData(roomID);
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ class Message
|
|||
{
|
||||
public:
|
||||
// explicit Message(const QString &text);
|
||||
//explicit Message(const QString &text, const std::vector<messages::Word> &words,
|
||||
// explicit Message(const QString &text, const std::vector<messages::Word> &words,
|
||||
// const bool &highlight);
|
||||
|
||||
bool getCanHighlightTab() const;
|
||||
|
@ -39,6 +39,7 @@ public:
|
|||
const QString &getId() const;
|
||||
|
||||
const QString text;
|
||||
bool centered = false;
|
||||
|
||||
private:
|
||||
static LazyLoadedImage *badgeStaff;
|
||||
|
|
|
@ -12,7 +12,7 @@ MessageBuilder::MessageBuilder()
|
|||
_parseTime = std::chrono::system_clock::now();
|
||||
}
|
||||
|
||||
SharedMessage MessageBuilder::build()
|
||||
SharedMessage MessageBuilder::getMessage()
|
||||
{
|
||||
return this->message;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ class MessageBuilder
|
|||
public:
|
||||
MessageBuilder();
|
||||
|
||||
SharedMessage build();
|
||||
SharedMessage getMessage();
|
||||
|
||||
void appendWord(const Word &&word);
|
||||
void appendTimestamp();
|
||||
|
|
|
@ -129,7 +129,7 @@ bool MessageRef::layout(int width, bool enableEmoteMargins)
|
|||
|
||||
// word wrapping
|
||||
if (word.isText() && word.getWidth() + MARGIN_LEFT > right) {
|
||||
alignWordParts(lineStart, lineHeight);
|
||||
alignWordParts(lineStart, lineHeight, width);
|
||||
|
||||
y += lineHeight;
|
||||
|
||||
|
@ -183,7 +183,7 @@ bool MessageRef::layout(int width, bool enableEmoteMargins)
|
|||
first = false;
|
||||
} else {
|
||||
// doesn't fit in the line
|
||||
alignWordParts(lineStart, lineHeight);
|
||||
alignWordParts(lineStart, lineHeight, width);
|
||||
|
||||
y += lineHeight;
|
||||
|
||||
|
@ -201,7 +201,7 @@ bool MessageRef::layout(int width, bool enableEmoteMargins)
|
|||
}
|
||||
}
|
||||
|
||||
alignWordParts(lineStart, lineHeight);
|
||||
alignWordParts(lineStart, lineHeight, width);
|
||||
|
||||
if (_height != y + lineHeight) {
|
||||
sizeChanged = true;
|
||||
|
@ -224,12 +224,18 @@ const std::vector<WordPart> &MessageRef::getWordParts() const
|
|||
return _wordParts;
|
||||
}
|
||||
|
||||
void MessageRef::alignWordParts(int lineStart, int lineHeight)
|
||||
void MessageRef::alignWordParts(int lineStart, int lineHeight, int width)
|
||||
{
|
||||
for (size_t i = lineStart; i < _wordParts.size(); i++) {
|
||||
WordPart &wordPart2 = _wordParts.at(i);
|
||||
int xOffset = 0;
|
||||
|
||||
wordPart2.setY(wordPart2.getY() + lineHeight);
|
||||
if (this->_message->centered && _wordParts.size() > 0) {
|
||||
xOffset = (width - this->_wordParts.at(_wordParts.size() - 1).getRight()) / 2;
|
||||
}
|
||||
|
||||
for (size_t i = lineStart; i < this->_wordParts.size(); i++) {
|
||||
WordPart &wordPart2 = this->_wordParts.at(i);
|
||||
|
||||
wordPart2.setPosition(wordPart2.getX() + xOffset, wordPart2.getY() + lineHeight);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ private:
|
|||
Word::Type _currentWordTypes = Word::None;
|
||||
|
||||
// methods
|
||||
void alignWordParts(int lineStart, int lineHeight);
|
||||
void alignWordParts(int lineStart, int lineHeight, int width);
|
||||
};
|
||||
|
||||
} // namespace messages
|
||||
|
|
|
@ -77,9 +77,11 @@ public:
|
|||
EmojiImage = (1 << 23),
|
||||
EmojiText = (1 << 24),
|
||||
|
||||
AlwaysShow = (1 << 25),
|
||||
|
||||
Default = TimestampNoSeconds | Badges | Username | BitsStatic | FfzEmoteImage |
|
||||
BttvEmoteImage | BttvGifEmoteImage | TwitchEmoteImage | BitsAmount | Text |
|
||||
ButtonBan | ButtonTimeout
|
||||
ButtonBan | ButtonTimeout | AlwaysShow
|
||||
};
|
||||
|
||||
Word()
|
||||
|
|
|
@ -146,6 +146,8 @@ void SettingsManager::updateWordTypeMask()
|
|||
|
||||
newMaskUint |= Word::Username;
|
||||
|
||||
newMaskUint |= Word::AlwaysShow;
|
||||
|
||||
Word::Type newMask = static_cast<Word::Type>(newMaskUint);
|
||||
|
||||
if (newMask != _wordTypeMask) {
|
||||
|
|
80
src/twitch/twitchchannel.cpp
Normal file
80
src/twitch/twitchchannel.cpp
Normal file
|
@ -0,0 +1,80 @@
|
|||
#include "twitchchannel.hpp"
|
||||
#include "emotemanager.hpp"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
namespace chatterino {
|
||||
namespace twitch {
|
||||
|
||||
TwitchChannel::TwitchChannel(EmoteManager &emoteManager, IrcManager &ircManager,
|
||||
const QString &channelName, bool isSpecial)
|
||||
: emoteManager(emoteManager)
|
||||
, ircManager(ircManager)
|
||||
// , name(channelName)
|
||||
, bttvChannelEmotes(new EmoteMap)
|
||||
, ffzChannelEmotes(new EmoteMap)
|
||||
, subLink("https://www.twitch.tv/" + name + "/subscribe?ref=in_chat_subscriber_link")
|
||||
, channelLink("https://twitch.tv/" + name)
|
||||
, popoutPlayerLink("https://player.twitch.tv/?channel=" + name)
|
||||
, isLive(false)
|
||||
, isSpecial(isSpecial)
|
||||
{
|
||||
this->name = channelName;
|
||||
|
||||
qDebug() << "Open twitch channel:" << this->name;
|
||||
|
||||
if (!isSpecial) {
|
||||
this->reloadChannelEmotes();
|
||||
}
|
||||
}
|
||||
|
||||
bool TwitchChannel::isEmpty() const
|
||||
{
|
||||
return this->name.isEmpty();
|
||||
}
|
||||
|
||||
const QString &TwitchChannel::getSubLink() const
|
||||
{
|
||||
return this->subLink;
|
||||
}
|
||||
|
||||
bool TwitchChannel::canSendMessage() const
|
||||
{
|
||||
return !this->isEmpty() && !this->isSpecial;
|
||||
}
|
||||
|
||||
const QString &TwitchChannel::getChannelLink() const
|
||||
{
|
||||
return this->channelLink;
|
||||
}
|
||||
|
||||
const QString &TwitchChannel::getPopoutPlayerLink() const
|
||||
{
|
||||
return this->popoutPlayerLink;
|
||||
}
|
||||
|
||||
void TwitchChannel::setRoomID(std::string id)
|
||||
{
|
||||
this->roomID = id;
|
||||
this->roomIDchanged();
|
||||
}
|
||||
|
||||
void TwitchChannel::reloadChannelEmotes()
|
||||
{
|
||||
printf("[TwitchChannel:%s] Reloading channel emotes\n", qPrintable(this->name));
|
||||
|
||||
this->emoteManager.reloadBTTVChannelEmotes(this->name, this->bttvChannelEmotes);
|
||||
this->emoteManager.reloadFFZChannelEmotes(this->name, this->ffzChannelEmotes);
|
||||
}
|
||||
|
||||
void TwitchChannel::sendMessage(const QString &message)
|
||||
{
|
||||
qDebug() << "TwitchChannel send message: " << message;
|
||||
|
||||
// Do last message processing
|
||||
QString parsedMessage = this->emoteManager.replaceShortCodes(message);
|
||||
|
||||
this->ircManager.sendMessage(this->name, parsedMessage);
|
||||
}
|
||||
}
|
||||
}
|
49
src/twitch/twitchchannel.hpp
Normal file
49
src/twitch/twitchchannel.hpp
Normal file
|
@ -0,0 +1,49 @@
|
|||
#pragma once
|
||||
|
||||
#include "channel.hpp"
|
||||
#include "concurrentmap.hpp"
|
||||
#include "ircmanager.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
namespace twitch {
|
||||
|
||||
class TwitchChannel : public Channel
|
||||
{
|
||||
public:
|
||||
explicit TwitchChannel(EmoteManager &emoteManager, IrcManager &ircManager,
|
||||
const QString &channelName, bool isSpecial = false);
|
||||
|
||||
void reloadChannelEmotes();
|
||||
|
||||
bool isEmpty() const override;
|
||||
bool canSendMessage() const override;
|
||||
void sendMessage(const QString &message) override;
|
||||
|
||||
const QString &getSubLink() const;
|
||||
const QString &getChannelLink() const;
|
||||
const QString &getPopoutPlayerLink() const;
|
||||
|
||||
void setRoomID(std::string id);
|
||||
boost::signals2::signal<void()> roomIDchanged;
|
||||
|
||||
std::string roomID;
|
||||
bool isLive;
|
||||
QString streamViewerCount;
|
||||
QString streamStatus;
|
||||
QString streamGame;
|
||||
QString streamUptime;
|
||||
|
||||
const std::shared_ptr<EmoteMap> bttvChannelEmotes;
|
||||
const std::shared_ptr<EmoteMap> ffzChannelEmotes;
|
||||
|
||||
private:
|
||||
EmoteManager &emoteManager;
|
||||
IrcManager &ircManager;
|
||||
|
||||
QString subLink;
|
||||
QString channelLink;
|
||||
QString popoutPlayerLink;
|
||||
bool isSpecial;
|
||||
};
|
||||
}
|
||||
}
|
|
@ -15,12 +15,13 @@ using namespace chatterino::messages;
|
|||
namespace chatterino {
|
||||
namespace twitch {
|
||||
|
||||
TwitchMessageBuilder::TwitchMessageBuilder(Channel *_channel, Resources &_resources,
|
||||
TwitchMessageBuilder::TwitchMessageBuilder(TwitchChannel *_channel, Resources &_resources,
|
||||
EmoteManager &_emoteManager,
|
||||
WindowManager &_windowManager,
|
||||
const Communi::IrcPrivateMessage *_ircMessage,
|
||||
const messages::MessageParseArgs &_args)
|
||||
: channel(_channel)
|
||||
, twitchChannel(_channel)
|
||||
, resources(_resources)
|
||||
, windowManager(_windowManager)
|
||||
, colorScheme(this->windowManager.colorScheme)
|
||||
|
@ -249,7 +250,7 @@ SharedMessage TwitchMessageBuilder::parse()
|
|||
// HighlightTab = false;
|
||||
// }
|
||||
|
||||
return this->build();
|
||||
return this->getMessage();
|
||||
}
|
||||
|
||||
void TwitchMessageBuilder::parseMessageID()
|
||||
|
@ -264,11 +265,12 @@ void TwitchMessageBuilder::parseMessageID()
|
|||
void TwitchMessageBuilder::parseRoomID()
|
||||
{
|
||||
auto iterator = this->tags.find("room-id");
|
||||
|
||||
if (iterator != std::end(this->tags)) {
|
||||
this->roomID = iterator.value().toString().toStdString();
|
||||
|
||||
if (this->channel->roomID.empty()) {
|
||||
this->channel->roomID = this->roomID;
|
||||
if (this->twitchChannel->roomID.empty()) {
|
||||
this->twitchChannel->roomID = this->roomID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -503,13 +505,13 @@ bool TwitchMessageBuilder::tryAppendEmote(QString &emoteString)
|
|||
if (emoteManager.bttvGlobalEmotes.tryGet(emoteString, emoteData)) {
|
||||
// BTTV Global Emote
|
||||
return this->appendEmote(emoteData);
|
||||
} else if (this->channel->bttvChannelEmotes.tryGet(emoteString, emoteData)) {
|
||||
} else if (this->twitchChannel->bttvChannelEmotes->tryGet(emoteString, emoteData)) {
|
||||
// BTTV Channel Emote
|
||||
return this->appendEmote(emoteData);
|
||||
} else if (emoteManager.ffzGlobalEmotes.tryGet(emoteString, emoteData)) {
|
||||
// FFZ Global Emote
|
||||
return this->appendEmote(emoteData);
|
||||
} else if (this->channel->ffzChannelEmotes.tryGet(emoteString, emoteData)) {
|
||||
} else if (this->twitchChannel->ffzChannelEmotes->tryGet(emoteString, emoteData)) {
|
||||
// FFZ Channel Emote
|
||||
return this->appendEmote(emoteData);
|
||||
} else if (emoteManager.getChatterinoEmotes().tryGet(emoteString, emoteData)) {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "emotemanager.hpp"
|
||||
#include "messages/messagebuilder.hpp"
|
||||
#include "resources.hpp"
|
||||
#include "twitch/twitchchannel.hpp"
|
||||
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
|
@ -26,12 +27,13 @@ public:
|
|||
|
||||
TwitchMessageBuilder() = delete;
|
||||
|
||||
explicit TwitchMessageBuilder(Channel *_channel, Resources &_resources,
|
||||
explicit TwitchMessageBuilder(TwitchChannel *_channel, Resources &_resources,
|
||||
EmoteManager &_emoteManager, WindowManager &_windowManager,
|
||||
const Communi::IrcPrivateMessage *_ircMessage,
|
||||
const messages::MessageParseArgs &_args);
|
||||
|
||||
Channel *channel;
|
||||
TwitchChannel *twitchChannel;
|
||||
Resources &resources;
|
||||
WindowManager &windowManager;
|
||||
ColorScheme &colorScheme;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "widgets/chatwidgetview.hpp"
|
||||
#include "widgets/channelview.hpp"
|
||||
#include "channelmanager.hpp"
|
||||
#include "colorscheme.hpp"
|
||||
#include "messages/limitedqueuesnapshot.hpp"
|
||||
|
@ -20,14 +20,15 @@
|
|||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
using namespace chatterino::messages;
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
ChatWidgetView::ChatWidgetView(ChatWidget *_chatWidget)
|
||||
: BaseWidget(_chatWidget)
|
||||
, chatWidget(_chatWidget)
|
||||
ChannelView::ChannelView(BaseWidget *parent)
|
||||
: BaseWidget(parent)
|
||||
, scrollBar(this)
|
||||
, userPopupWidget(_chatWidget->getChannelRef())
|
||||
, userPopupWidget(std::shared_ptr<Channel>())
|
||||
{
|
||||
#ifndef Q_OS_MAC
|
||||
// this->setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
|
@ -35,7 +36,7 @@ ChatWidgetView::ChatWidgetView(ChatWidget *_chatWidget)
|
|||
this->setMouseTracking(true);
|
||||
|
||||
QObject::connect(&SettingsManager::getInstance(), &SettingsManager::wordTypeMaskChanged, this,
|
||||
&ChatWidgetView::wordTypeMaskChanged);
|
||||
&ChannelView::wordTypeMaskChanged);
|
||||
|
||||
this->scrollBar.getCurrentValueChanged().connect([this] {
|
||||
// Whenever the scrollbar value has been changed, re-render the ChatWidgetView
|
||||
|
@ -45,15 +46,15 @@ ChatWidgetView::ChatWidgetView(ChatWidget *_chatWidget)
|
|||
});
|
||||
}
|
||||
|
||||
ChatWidgetView::~ChatWidgetView()
|
||||
ChannelView::~ChannelView()
|
||||
{
|
||||
QObject::disconnect(&SettingsManager::getInstance(), &SettingsManager::wordTypeMaskChanged,
|
||||
this, &ChatWidgetView::wordTypeMaskChanged);
|
||||
this, &ChannelView::wordTypeMaskChanged);
|
||||
}
|
||||
|
||||
bool ChatWidgetView::layoutMessages()
|
||||
bool ChannelView::layoutMessages()
|
||||
{
|
||||
auto messages = this->chatWidget->getMessagesSnapshot();
|
||||
auto messages = this->getMessagesSnapshot();
|
||||
|
||||
if (messages.getLength() == 0) {
|
||||
this->scrollBar.setVisible(false);
|
||||
|
@ -130,21 +131,30 @@ bool ChatWidgetView::layoutMessages()
|
|||
return redraw;
|
||||
}
|
||||
|
||||
void ChatWidgetView::updateGifEmotes()
|
||||
void ChannelView::clearMessages()
|
||||
{
|
||||
// Clear all stored messages in this chat widget
|
||||
this->messages.clear();
|
||||
|
||||
// Layout chat widget messages, and force an update regardless if there are no messages
|
||||
this->layoutMessages();
|
||||
this->update();
|
||||
}
|
||||
|
||||
void ChannelView::updateGifEmotes()
|
||||
{
|
||||
this->onlyUpdateEmotes = true;
|
||||
this->update();
|
||||
}
|
||||
|
||||
ScrollBar &ChatWidgetView::getScrollBar()
|
||||
ScrollBar &ChannelView::getScrollBar()
|
||||
{
|
||||
return this->scrollBar;
|
||||
}
|
||||
|
||||
QString ChatWidgetView::getSelectedText() const
|
||||
QString ChannelView::getSelectedText()
|
||||
{
|
||||
messages::LimitedQueueSnapshot<messages::SharedMessageRef> messages =
|
||||
this->chatWidget->getMessagesSnapshot();
|
||||
LimitedQueueSnapshot<SharedMessageRef> messages = this->getMessagesSnapshot();
|
||||
|
||||
QString text;
|
||||
bool isSingleMessage = this->selection.isSingleMessage();
|
||||
|
@ -232,7 +242,72 @@ QString ChatWidgetView::getSelectedText() const
|
|||
return text;
|
||||
}
|
||||
|
||||
void ChatWidgetView::resizeEvent(QResizeEvent *)
|
||||
messages::LimitedQueueSnapshot<SharedMessageRef> ChannelView::getMessagesSnapshot()
|
||||
{
|
||||
return this->messages.getSnapshot();
|
||||
}
|
||||
|
||||
void ChannelView::setChannel(std::shared_ptr<Channel> channel)
|
||||
{
|
||||
if (this->channel) {
|
||||
this->detachChannel();
|
||||
}
|
||||
this->messages.clear();
|
||||
|
||||
// on new message
|
||||
this->messageAppendedConnection =
|
||||
channel->messageAppended.connect([this](SharedMessage &message) {
|
||||
SharedMessageRef deleted;
|
||||
|
||||
auto messageRef = new MessageRef(message);
|
||||
|
||||
if (this->messages.appendItem(SharedMessageRef(messageRef), deleted)) {
|
||||
qreal value = std::max(0.0, this->getScrollBar().getDesiredValue() - 1);
|
||||
|
||||
this->getScrollBar().setDesiredValue(value, false);
|
||||
}
|
||||
|
||||
layoutMessages();
|
||||
update();
|
||||
});
|
||||
|
||||
// on message removed
|
||||
this->messageRemovedConnection =
|
||||
channel->messageRemovedFromStart.connect([this](SharedMessage &) {
|
||||
this->selection.min.messageIndex--;
|
||||
this->selection.max.messageIndex--;
|
||||
this->selection.start.messageIndex--;
|
||||
this->selection.end.messageIndex--;
|
||||
|
||||
layoutMessages();
|
||||
update();
|
||||
});
|
||||
|
||||
auto snapshot = channel->getMessageSnapshot();
|
||||
|
||||
for (size_t i = 0; i < snapshot.getLength(); i++) {
|
||||
SharedMessageRef deleted;
|
||||
|
||||
auto messageRef = new MessageRef(snapshot[i]);
|
||||
|
||||
this->messages.appendItem(SharedMessageRef(messageRef), deleted);
|
||||
}
|
||||
|
||||
this->channel = channel;
|
||||
|
||||
this->userPopupWidget.setChannel(channel);
|
||||
}
|
||||
|
||||
void ChannelView::detachChannel()
|
||||
{
|
||||
// on message added
|
||||
this->messageAppendedConnection.disconnect();
|
||||
|
||||
// on message removed
|
||||
this->messageRemovedConnection.disconnect();
|
||||
}
|
||||
|
||||
void ChannelView::resizeEvent(QResizeEvent *)
|
||||
{
|
||||
this->scrollBar.resize(this->scrollBar.width(), height());
|
||||
this->scrollBar.move(width() - this->scrollBar.width(), 0);
|
||||
|
@ -242,7 +317,7 @@ void ChatWidgetView::resizeEvent(QResizeEvent *)
|
|||
this->update();
|
||||
}
|
||||
|
||||
void ChatWidgetView::setSelection(const SelectionItem &start, const SelectionItem &end)
|
||||
void ChannelView::setSelection(const SelectionItem &start, const SelectionItem &end)
|
||||
{
|
||||
// selections
|
||||
this->selection = Selection(start, end);
|
||||
|
@ -251,7 +326,7 @@ void ChatWidgetView::setSelection(const SelectionItem &start, const SelectionIte
|
|||
// << max.charIndex;
|
||||
}
|
||||
|
||||
void ChatWidgetView::paintEvent(QPaintEvent * /*event*/)
|
||||
void ChannelView::paintEvent(QPaintEvent * /*event*/)
|
||||
{
|
||||
QPainter painter(this);
|
||||
|
||||
|
@ -288,9 +363,9 @@ void ChatWidgetView::paintEvent(QPaintEvent * /*event*/)
|
|||
}
|
||||
}
|
||||
|
||||
void ChatWidgetView::drawMessages(QPainter &painter)
|
||||
void ChannelView::drawMessages(QPainter &painter)
|
||||
{
|
||||
auto messages = this->chatWidget->getMessagesSnapshot();
|
||||
auto messages = this->getMessagesSnapshot();
|
||||
|
||||
size_t start = this->scrollBar.getCurrentValue();
|
||||
|
||||
|
@ -341,7 +416,9 @@ void ChatWidgetView::drawMessages(QPainter &painter)
|
|||
|
||||
messageRef->buffer = bufferPtr;
|
||||
|
||||
// if (buffer != nullptr) {
|
||||
painter.drawPixmap(0, y, *buffer);
|
||||
// }
|
||||
|
||||
y += messageRef->getHeight();
|
||||
|
||||
|
@ -351,8 +428,8 @@ void ChatWidgetView::drawMessages(QPainter &painter)
|
|||
}
|
||||
}
|
||||
|
||||
void ChatWidgetView::updateMessageBuffer(messages::MessageRef *messageRef, QPixmap *buffer,
|
||||
int messageIndex)
|
||||
void ChannelView::updateMessageBuffer(messages::MessageRef *messageRef, QPixmap *buffer,
|
||||
int messageIndex)
|
||||
{
|
||||
QPainter painter(buffer);
|
||||
|
||||
|
@ -403,8 +480,8 @@ void ChatWidgetView::updateMessageBuffer(messages::MessageRef *messageRef, QPixm
|
|||
messageRef->updateBuffer = false;
|
||||
}
|
||||
|
||||
void ChatWidgetView::drawMessageSelection(QPainter &painter, messages::MessageRef *messageRef,
|
||||
int messageIndex, int bufferHeight)
|
||||
void ChannelView::drawMessageSelection(QPainter &painter, messages::MessageRef *messageRef,
|
||||
int messageIndex, int bufferHeight)
|
||||
{
|
||||
if (this->selection.min.messageIndex > messageIndex ||
|
||||
this->selection.max.messageIndex < messageIndex) {
|
||||
|
@ -552,7 +629,7 @@ void ChatWidgetView::drawMessageSelection(QPainter &painter, messages::MessageRe
|
|||
painter.fillRect(rect, selectionColor);
|
||||
}
|
||||
|
||||
void ChatWidgetView::wheelEvent(QWheelEvent *event)
|
||||
void ChannelView::wheelEvent(QWheelEvent *event)
|
||||
{
|
||||
if (this->scrollBar.isVisible()) {
|
||||
auto mouseMultiplier = SettingsManager::getInstance().mouseScrollMultiplier.get();
|
||||
|
@ -562,7 +639,7 @@ void ChatWidgetView::wheelEvent(QWheelEvent *event)
|
|||
}
|
||||
}
|
||||
|
||||
void ChatWidgetView::mouseMoveEvent(QMouseEvent *event)
|
||||
void ChannelView::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
std::shared_ptr<messages::MessageRef> message;
|
||||
QPoint relativePos;
|
||||
|
@ -594,10 +671,8 @@ void ChatWidgetView::mouseMoveEvent(QMouseEvent *event)
|
|||
}
|
||||
}
|
||||
|
||||
void ChatWidgetView::mousePressEvent(QMouseEvent *event)
|
||||
void ChannelView::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
this->chatWidget->giveFocus(Qt::MouseFocusReason);
|
||||
|
||||
this->isMouseDown = true;
|
||||
|
||||
this->lastPressPosition = event->screenPos();
|
||||
|
@ -621,7 +696,7 @@ void ChatWidgetView::mousePressEvent(QMouseEvent *event)
|
|||
this->repaint();
|
||||
}
|
||||
|
||||
void ChatWidgetView::mouseReleaseEvent(QMouseEvent *event)
|
||||
void ChannelView::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
if (!this->isMouseDown) {
|
||||
// We didn't grab the mouse press, so we shouldn't be handling the mouse
|
||||
|
@ -682,10 +757,10 @@ void ChatWidgetView::mouseReleaseEvent(QMouseEvent *event)
|
|||
}
|
||||
}
|
||||
|
||||
bool ChatWidgetView::tryGetMessageAt(QPoint p, std::shared_ptr<messages::MessageRef> &_message,
|
||||
QPoint &relativePos, int &index)
|
||||
bool ChannelView::tryGetMessageAt(QPoint p, std::shared_ptr<messages::MessageRef> &_message,
|
||||
QPoint &relativePos, int &index)
|
||||
{
|
||||
auto messages = this->chatWidget->getMessagesSnapshot();
|
||||
auto messages = this->getMessagesSnapshot();
|
||||
|
||||
size_t start = this->scrollBar.getCurrentValue();
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "channel.hpp"
|
||||
#include "messages/lazyloadedimage.hpp"
|
||||
#include "messages/limitedqueuesnapshot.hpp"
|
||||
#include "messages/messageref.hpp"
|
||||
#include "messages/word.hpp"
|
||||
#include "widgets/accountpopup.hpp"
|
||||
|
@ -13,6 +14,8 @@
|
|||
#include <QWheelEvent>
|
||||
#include <QWidget>
|
||||
|
||||
#include <boost/signals2.hpp>
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
|
@ -75,21 +78,23 @@ struct Selection {
|
|||
}
|
||||
};
|
||||
|
||||
class ChatWidget;
|
||||
|
||||
class ChatWidgetView : public BaseWidget
|
||||
class ChannelView : public BaseWidget
|
||||
{
|
||||
friend class ChatWidget;
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ChatWidgetView(ChatWidget *_chatWidget);
|
||||
~ChatWidgetView();
|
||||
|
||||
bool layoutMessages();
|
||||
explicit ChannelView(BaseWidget *parent = 0);
|
||||
~ChannelView();
|
||||
|
||||
void updateGifEmotes();
|
||||
ScrollBar &getScrollBar();
|
||||
QString getSelectedText() const;
|
||||
QString getSelectedText();
|
||||
|
||||
void setChannel(std::shared_ptr<Channel> channel);
|
||||
messages::LimitedQueueSnapshot<messages::SharedMessageRef> getMessagesSnapshot();
|
||||
bool layoutMessages();
|
||||
|
||||
void clearMessages();
|
||||
|
||||
protected:
|
||||
virtual void resizeEvent(QResizeEvent *) override;
|
||||
|
@ -110,15 +115,17 @@ private:
|
|||
QRect rect;
|
||||
};
|
||||
|
||||
void detachChannel();
|
||||
|
||||
void drawMessages(QPainter &painter);
|
||||
void updateMessageBuffer(messages::MessageRef *messageRef, QPixmap *buffer, int messageIndex);
|
||||
void drawMessageSelection(QPainter &painter, messages::MessageRef *messageRef, int messageIndex,
|
||||
int bufferHeight);
|
||||
void setSelection(const SelectionItem &start, const SelectionItem &end);
|
||||
|
||||
std::vector<GifEmoteData> gifEmotes;
|
||||
std::shared_ptr<Channel> channel;
|
||||
|
||||
ChatWidget *const chatWidget;
|
||||
std::vector<GifEmoteData> gifEmotes;
|
||||
|
||||
ScrollBar scrollBar;
|
||||
|
||||
|
@ -136,6 +143,11 @@ private:
|
|||
Selection selection;
|
||||
bool selecting = false;
|
||||
|
||||
messages::LimitedQueue<messages::SharedMessageRef> messages;
|
||||
|
||||
boost::signals2::connection messageAppendedConnection;
|
||||
boost::signals2::connection messageRemovedConnection;
|
||||
|
||||
private slots:
|
||||
void wordTypeMaskChanged()
|
||||
{
|
|
@ -18,6 +18,7 @@
|
|||
#include <QPainter>
|
||||
#include <QProcess>
|
||||
#include <QShortcut>
|
||||
#include <QTimer>
|
||||
#include <QVBoxLayout>
|
||||
#include <boost/signals2.hpp>
|
||||
|
||||
|
@ -52,7 +53,7 @@ ChatWidget::ChatWidget(ChannelManager &_channelManager, NotebookPage *parent)
|
|||
, vbox(this)
|
||||
, header(this)
|
||||
, view(this)
|
||||
, input(this)
|
||||
, input(this, _channelManager.getEmoteManager())
|
||||
{
|
||||
this->vbox.setSpacing(0);
|
||||
this->vbox.setMargin(1);
|
||||
|
@ -80,11 +81,15 @@ ChatWidget::ChatWidget(ChannelManager &_channelManager, NotebookPage *parent)
|
|||
this->channelNameUpdated(this->channelName.getValue());
|
||||
|
||||
this->input.textInput.installEventFilter(parent);
|
||||
|
||||
connect(&view, &this->view.mousePressEvent, this, [&](QMouseEvent *) {
|
||||
QTimer::singleShot(10, [this] { this->giveFocus(Qt::MouseFocusReason); });
|
||||
});
|
||||
}
|
||||
|
||||
ChatWidget::~ChatWidget()
|
||||
{
|
||||
this->detachChannel();
|
||||
channelNameUpdated("");
|
||||
}
|
||||
|
||||
std::shared_ptr<Channel> ChatWidget::getChannel() const
|
||||
|
@ -99,82 +104,33 @@ std::shared_ptr<Channel> &ChatWidget::getChannelRef()
|
|||
|
||||
void ChatWidget::setChannel(std::shared_ptr<Channel> _newChannel)
|
||||
{
|
||||
this->view.setChannel(_newChannel);
|
||||
|
||||
this->channel = _newChannel;
|
||||
this->channel->roomIDchanged.connect([this]() { this->header.checkLive(); });
|
||||
|
||||
this->view.userPopupWidget.setChannel(_newChannel);
|
||||
|
||||
// on new message
|
||||
this->messageAppendedConnection =
|
||||
this->channel->messageAppended.connect([this](SharedMessage &message) {
|
||||
SharedMessageRef deleted;
|
||||
|
||||
auto messageRef = new MessageRef(message);
|
||||
|
||||
if (this->messages.appendItem(SharedMessageRef(messageRef), deleted)) {
|
||||
qreal value = std::max(0.0, this->view.getScrollBar().getDesiredValue() - 1);
|
||||
|
||||
this->view.getScrollBar().setDesiredValue(value, false);
|
||||
}
|
||||
});
|
||||
|
||||
// on message removed
|
||||
this->messageRemovedConnection =
|
||||
this->channel->messageRemovedFromStart.connect([this](SharedMessage &) {
|
||||
this->view.selection.min.messageIndex--;
|
||||
this->view.selection.max.messageIndex--;
|
||||
this->view.selection.start.messageIndex--;
|
||||
this->view.selection.end.messageIndex--;
|
||||
});
|
||||
|
||||
auto snapshot = this->channel->getMessageSnapshot();
|
||||
|
||||
for (size_t i = 0; i < snapshot.getLength(); i++) {
|
||||
SharedMessageRef deleted;
|
||||
|
||||
auto messageRef = new MessageRef(snapshot[i]);
|
||||
|
||||
this->messages.appendItem(SharedMessageRef(messageRef), deleted);
|
||||
twitch::TwitchChannel *twitchChannel = dynamic_cast<twitch::TwitchChannel *>(_newChannel.get());
|
||||
if (twitchChannel != nullptr) {
|
||||
twitchChannel->roomIDchanged.connect([this]() { this->header.checkLive(); });
|
||||
}
|
||||
}
|
||||
|
||||
void ChatWidget::detachChannel()
|
||||
{
|
||||
// on message added
|
||||
this->messageAppendedConnection.disconnect();
|
||||
|
||||
// on message removed
|
||||
this->messageRemovedConnection.disconnect();
|
||||
}
|
||||
|
||||
void ChatWidget::channelNameUpdated(const std::string &newChannelName)
|
||||
{
|
||||
// remove current channel
|
||||
if (!this->channel->isEmpty()) {
|
||||
this->channelManager.removeChannel(this->channel->name);
|
||||
|
||||
this->detachChannel();
|
||||
this->channelManager.removeTwitchChannel(this->channel->name);
|
||||
}
|
||||
|
||||
// update messages
|
||||
this->messages.clear();
|
||||
|
||||
if (newChannelName.empty()) {
|
||||
this->channel = this->channelManager.emptyChannel;
|
||||
this->setChannel(this->channelManager.emptyChannel);
|
||||
} else {
|
||||
this->setChannel(this->channelManager.addChannel(QString::fromStdString(newChannelName)));
|
||||
this->setChannel(
|
||||
this->channelManager.addTwitchChannel(QString::fromStdString(newChannelName)));
|
||||
}
|
||||
|
||||
// update header
|
||||
this->header.updateChannelText();
|
||||
|
||||
// update view
|
||||
this->layoutMessages(true);
|
||||
}
|
||||
|
||||
LimitedQueueSnapshot<SharedMessageRef> ChatWidget::getMessagesSnapshot()
|
||||
{
|
||||
return this->messages.getSnapshot();
|
||||
}
|
||||
|
||||
bool ChatWidget::showChangeChannelPopup(const char *dialogTitle, bool empty)
|
||||
|
@ -202,9 +158,12 @@ bool ChatWidget::showChangeChannelPopup(const char *dialogTitle, bool empty)
|
|||
|
||||
void ChatWidget::layoutMessages(bool forceUpdate)
|
||||
{
|
||||
if (this->view.layoutMessages() || forceUpdate) {
|
||||
this->view.update();
|
||||
}
|
||||
this->view.layoutMessages();
|
||||
this->view.update();
|
||||
|
||||
// if (this->view.layoutMessages() || forceUpdate) {
|
||||
// this->view.update();
|
||||
// }
|
||||
}
|
||||
|
||||
void ChatWidget::updateGifEmotes()
|
||||
|
@ -285,11 +244,7 @@ void ChatWidget::doPopup()
|
|||
|
||||
void ChatWidget::doClearChat()
|
||||
{
|
||||
// Clear all stored messages in this chat widget
|
||||
this->messages.clear();
|
||||
|
||||
// Layout chat widget messages, and force an update regardless if there are no messages
|
||||
this->layoutMessages(true);
|
||||
view.clearMessages();
|
||||
}
|
||||
|
||||
void ChatWidget::doOpenChannel()
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
#include "messages/word.hpp"
|
||||
#include "messages/wordpart.hpp"
|
||||
#include "widgets/basewidget.hpp"
|
||||
#include "widgets/channelview.hpp"
|
||||
#include "widgets/chatwidgetheader.hpp"
|
||||
#include "widgets/chatwidgetinput.hpp"
|
||||
#include "widgets/chatwidgetview.hpp"
|
||||
|
||||
#include <QFont>
|
||||
#include <QShortcut>
|
||||
|
@ -49,13 +49,13 @@ public:
|
|||
std::shared_ptr<Channel> &getChannelRef();
|
||||
|
||||
bool showChangeChannelPopup(const char *dialogTitle, bool empty = false);
|
||||
messages::LimitedQueueSnapshot<messages::SharedMessageRef> getMessagesSnapshot();
|
||||
void layoutMessages(bool forceUpdate = false);
|
||||
void updateGifEmotes();
|
||||
|
||||
void giveFocus(Qt::FocusReason reason);
|
||||
bool hasFocus() const;
|
||||
|
||||
void layoutMessages(bool forceUpdate = false);
|
||||
void updateGifEmotes();
|
||||
|
||||
protected:
|
||||
virtual void paintEvent(QPaintEvent *) override;
|
||||
|
||||
|
@ -67,24 +67,20 @@ public:
|
|||
|
||||
private:
|
||||
void setChannel(std::shared_ptr<Channel> newChannel);
|
||||
void detachChannel();
|
||||
void doOpenAccountPopupWidget(AccountPopupWidget *widget, QString user);
|
||||
|
||||
void channelNameUpdated(const std::string &newChannelName);
|
||||
|
||||
NotebookPage &parentPage;
|
||||
|
||||
messages::LimitedQueue<messages::SharedMessageRef> messages;
|
||||
|
||||
std::shared_ptr<Channel> channel;
|
||||
|
||||
QVBoxLayout vbox;
|
||||
ChatWidgetHeader header;
|
||||
ChatWidgetView view;
|
||||
ChannelView view;
|
||||
ChatWidgetInput input;
|
||||
|
||||
boost::signals2::connection messageAppendedConnection;
|
||||
boost::signals2::connection messageRemovedConnection;
|
||||
boost::signals2::connection channelIDChangedConnection;
|
||||
|
||||
public:
|
||||
void load(const boost::property_tree::ptree &tree);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "widgets/chatwidgetheader.hpp"
|
||||
#include "colorscheme.hpp"
|
||||
#include "twitch/twitchchannel.hpp"
|
||||
#include "util/urlfetch.hpp"
|
||||
#include "widgets/chatwidget.hpp"
|
||||
#include "widgets/notebookpage.hpp"
|
||||
|
@ -81,16 +82,22 @@ void ChatWidgetHeader::updateChannelText()
|
|||
if (channelName.empty()) {
|
||||
this->channelNameLabel.setText("<no channel>");
|
||||
} else {
|
||||
if (this->chatWidget->getChannelRef()->isLive) {
|
||||
auto channel = this->chatWidget->getChannelRef();
|
||||
auto channel = this->chatWidget->getChannel();
|
||||
|
||||
twitch::TwitchChannel *twitchChannel = dynamic_cast<twitch::TwitchChannel *>(channel.get());
|
||||
|
||||
if (channel->isEmpty()) {
|
||||
this->channelNameLabel.setText(QString::fromStdString(channelName) + " (live)");
|
||||
this->setToolTip(
|
||||
"<style>.center { text-align: center; }</style>"
|
||||
"<p class = \"center\">" +
|
||||
channel->streamStatus + "<br><br>" + channel->streamGame + "<br>"
|
||||
"Live for " +
|
||||
channel->streamUptime + " with " + channel->streamViewerCount + " viewers"
|
||||
"</p>");
|
||||
if (twitchChannel != nullptr) {
|
||||
this->setToolTip("<style>.center { text-align: center; }</style>"
|
||||
"<p class = \"center\">" +
|
||||
twitchChannel->streamStatus + "<br><br>" +
|
||||
twitchChannel->streamGame + "<br>"
|
||||
"Live for " +
|
||||
twitchChannel->streamUptime + " with " +
|
||||
twitchChannel->streamViewerCount + " viewers"
|
||||
"</p>");
|
||||
}
|
||||
} else {
|
||||
this->channelNameLabel.setText(QString::fromStdString(channelName));
|
||||
this->setToolTip("");
|
||||
|
@ -157,7 +164,7 @@ void ChatWidgetHeader::mouseDoubleClickEvent(QMouseEvent *event)
|
|||
|
||||
void ChatWidgetHeader::leftButtonClicked()
|
||||
{
|
||||
QTimer::singleShot(100, [&] {
|
||||
QTimer::singleShot(80, [&] {
|
||||
this->leftMenu.move(this->leftLabel.mapToGlobal(QPoint(0, this->leftLabel.height())));
|
||||
this->leftMenu.show();
|
||||
});
|
||||
|
@ -193,10 +200,18 @@ void ChatWidgetHeader::menuShowChangelog()
|
|||
{
|
||||
}
|
||||
|
||||
// TODO: this needs to be moved out of here
|
||||
void ChatWidgetHeader::checkLive()
|
||||
{
|
||||
auto channel = this->chatWidget->getChannelRef();
|
||||
twitch::TwitchChannel *channel =
|
||||
dynamic_cast<twitch::TwitchChannel *>(this->chatWidget->getChannel().get());
|
||||
|
||||
if (channel == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto id = QString::fromStdString(channel->roomID);
|
||||
|
||||
util::twitch::get("https://api.twitch.tv/kraken/streams/" + id, [=](QJsonObject obj) {
|
||||
if (obj.value("stream").isNull()) {
|
||||
channel->isLive = false;
|
||||
|
|
|
@ -23,12 +23,12 @@ ChatWidgetHeaderButton::ChatWidgetHeaderButton(BaseWidget *parent, int spacing)
|
|||
this->setMouseEffectColor(QColor(255, 255, 255, 63));
|
||||
}
|
||||
|
||||
void ChatWidgetHeaderButton::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter painter(this);
|
||||
// void ChatWidgetHeaderButton::paintEvent(QPaintEvent *)
|
||||
//{
|
||||
// QPainter painter(this);
|
||||
|
||||
this->fancyPaint(painter);
|
||||
}
|
||||
// this->fancyPaint(painter);
|
||||
//}
|
||||
|
||||
} // namespace widgets
|
||||
} // namespace chatterino
|
||||
|
|
|
@ -28,7 +28,7 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
virtual void paintEvent(QPaintEvent *) override;
|
||||
// virtual void paintEvent(QPaintEvent *) override;
|
||||
|
||||
private:
|
||||
struct {
|
||||
|
|
|
@ -13,9 +13,10 @@
|
|||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
ChatWidgetInput::ChatWidgetInput(ChatWidget *_chatWidget)
|
||||
ChatWidgetInput::ChatWidgetInput(ChatWidget *_chatWidget, EmoteManager &emoteManager)
|
||||
: BaseWidget(_chatWidget)
|
||||
, chatWidget(_chatWidget)
|
||||
, emoteManager(emoteManager)
|
||||
, emotesLabel(this)
|
||||
{
|
||||
this->setMaximumHeight(150);
|
||||
|
@ -46,10 +47,12 @@ ChatWidgetInput::ChatWidgetInput(ChatWidget *_chatWidget)
|
|||
|
||||
connect(&this->emotesLabel, &ChatWidgetHeaderButton::clicked, [this] {
|
||||
if (this->emotePopup == nullptr) {
|
||||
this->emotePopup = new EmotePopup();
|
||||
this->emotePopup = new EmotePopup(this->colorScheme, this->emoteManager);
|
||||
}
|
||||
|
||||
this->emotePopup->show(); //
|
||||
this->emotePopup->resize(300, 500);
|
||||
this->emotePopup->loadChannel(this->chatWidget->getChannel());
|
||||
this->emotePopup->show();
|
||||
});
|
||||
|
||||
connect(&textInput, &ResizingTextEdit::textChanged, this, &ChatWidgetInput::editTextChanged);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "emotemanager.hpp"
|
||||
#include "resizingtextedit.hpp"
|
||||
#include "widgets/basewidget.hpp"
|
||||
#include "widgets/chatwidgetheaderbutton.hpp"
|
||||
|
@ -25,7 +26,7 @@ class ChatWidgetInput : public BaseWidget
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ChatWidgetInput(ChatWidget *_chatWidget);
|
||||
ChatWidgetInput(ChatWidget *_chatWidget, EmoteManager &);
|
||||
~ChatWidgetInput();
|
||||
|
||||
protected:
|
||||
|
@ -37,6 +38,7 @@ protected:
|
|||
private:
|
||||
ChatWidget *const chatWidget;
|
||||
EmotePopup *emotePopup = nullptr;
|
||||
EmoteManager &emoteManager;
|
||||
|
||||
boost::signals2::connection textLengthVisibleChangedConnection;
|
||||
QHBoxLayout hbox;
|
||||
|
|
|
@ -1,18 +1,70 @@
|
|||
#include "emotepopup.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
|
||||
#include "messages/messagebuilder.hpp"
|
||||
#include "twitch/twitchchannel.hpp"
|
||||
|
||||
using namespace chatterino::twitch;
|
||||
using namespace chatterino::messages;
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
EmotePopup::EmotePopup(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
EmotePopup::EmotePopup(ColorScheme &colorScheme, EmoteManager &emoteManager)
|
||||
: BaseWidget(colorScheme, 0)
|
||||
, emoteManager(emoteManager)
|
||||
{
|
||||
QHBoxLayout *layout = new QHBoxLayout(this);
|
||||
this->setLayout(layout);
|
||||
layout->setMargin(0);
|
||||
|
||||
view = new ChannelView(this);
|
||||
layout->addWidget(view);
|
||||
}
|
||||
|
||||
void EmotePopup::loadChannel(std::shared_ptr<Channel> channel)
|
||||
void EmotePopup::loadChannel(std::shared_ptr<Channel> _channel)
|
||||
{
|
||||
// channel->bttvChannelEmotes.each([](const QString &key, const EmoteData &value) {
|
||||
TwitchChannel *channel = dynamic_cast<TwitchChannel *>(_channel.get());
|
||||
|
||||
// //
|
||||
// });
|
||||
if (channel == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<Channel> emoteChannel(new Channel);
|
||||
|
||||
auto addEmotes = [&](EmoteMap &map, const QString &title, const QString &emoteDesc) {
|
||||
// TITLE
|
||||
messages::MessageBuilder builder1;
|
||||
|
||||
builder1.appendWord(
|
||||
Word(title, Word::Type::Text, QColor(255, 255, 255), QString(), QString()));
|
||||
|
||||
builder1.getMessage()->centered = true;
|
||||
emoteChannel->addMessage(builder1.getMessage());
|
||||
|
||||
// EMOTES
|
||||
messages::MessageBuilder builder2;
|
||||
builder2.getMessage()->centered = true;
|
||||
|
||||
map.each([&](const QString &key, const EmoteData &value) {
|
||||
builder2.appendWord(Word(value.image, Word::Type::AlwaysShow, key, emoteDesc,
|
||||
Link(Link::Type::InsertText, key)));
|
||||
});
|
||||
|
||||
emoteChannel->addMessage(builder2.getMessage());
|
||||
};
|
||||
|
||||
addEmotes(this->emoteManager.bttvGlobalEmotes, "BetterTTV Global Emotes",
|
||||
"BetterTTV Global Emote");
|
||||
addEmotes(*channel->bttvChannelEmotes.get(), "BetterTTV Channel Emotes",
|
||||
"BetterTTV Channel Emote");
|
||||
addEmotes(this->emoteManager.ffzGlobalEmotes, "FrankerFaceZ Global Emotes",
|
||||
"FrankerFaceZ Global Emote");
|
||||
addEmotes(*channel->ffzChannelEmotes.get(), "FrankerFaceZ Channel Emotes",
|
||||
"FrankerFaceZ Channel Emote");
|
||||
|
||||
view->setChannel(emoteChannel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +1,23 @@
|
|||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "channel.hpp"
|
||||
#include "emotemanager.hpp"
|
||||
#include "widgets/basewidget.hpp"
|
||||
#include "widgets/channelview.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
class EmotePopup : public QWidget
|
||||
class EmotePopup : public BaseWidget
|
||||
{
|
||||
public:
|
||||
explicit EmotePopup(QWidget *parent = 0);
|
||||
explicit EmotePopup(ColorScheme &, EmoteManager &);
|
||||
|
||||
void loadChannel(std::shared_ptr<Channel> channel);
|
||||
|
||||
private:
|
||||
ChannelView *view;
|
||||
EmoteManager &emoteManager;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ void FancyButton::setMouseEffectColor(QColor color)
|
|||
|
||||
void FancyButton::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter painter;
|
||||
QPainter painter(this);
|
||||
|
||||
this->fancyPaint(painter);
|
||||
}
|
||||
|
|
|
@ -212,7 +212,7 @@ void Notebook::resizeEvent(QResizeEvent *)
|
|||
|
||||
void Notebook::settingsButtonClicked()
|
||||
{
|
||||
QTimer::singleShot(100, [this] { SettingsDialog::showDialog(); });
|
||||
QTimer::singleShot(80, [this] { SettingsDialog::showDialog(); });
|
||||
}
|
||||
|
||||
void Notebook::usersButtonClicked()
|
||||
|
@ -221,7 +221,7 @@ void Notebook::usersButtonClicked()
|
|||
|
||||
void Notebook::addPageButtonClicked()
|
||||
{
|
||||
QTimer::singleShot(100, [this] { this->addPage(true); });
|
||||
QTimer::singleShot(80, [this] { this->addPage(true); });
|
||||
}
|
||||
|
||||
void Notebook::load(const boost::property_tree::ptree &tree)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "widgets/scrollbar.hpp"
|
||||
#include "colorscheme.hpp"
|
||||
#include "widgets/chatwidgetview.hpp"
|
||||
#include "widgets/channelview.hpp"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QMouseEvent>
|
||||
|
@ -11,7 +11,7 @@
|
|||
namespace chatterino {
|
||||
namespace widgets {
|
||||
|
||||
ScrollBar::ScrollBar(ChatWidgetView *parent)
|
||||
ScrollBar::ScrollBar(ChannelView *parent)
|
||||
: BaseWidget(parent)
|
||||
, _currentValueAnimation(this, "_currentValue")
|
||||
, _highlights(nullptr)
|
||||
|
|
|
@ -14,14 +14,14 @@ class ColorScheme;
|
|||
|
||||
namespace widgets {
|
||||
|
||||
class ChatWidgetView;
|
||||
class ChannelView;
|
||||
|
||||
class ScrollBar : public BaseWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ScrollBar(ChatWidgetView *parent = 0);
|
||||
ScrollBar(ChannelView *parent = 0);
|
||||
~ScrollBar();
|
||||
|
||||
void removeHighlightsWhere(std::function<bool(ScrollBarHighlight &)> func);
|
||||
|
|
|
@ -46,12 +46,12 @@ void WindowManager::repaintGifEmotes()
|
|||
}
|
||||
}
|
||||
|
||||
void WindowManager::updateAll()
|
||||
{
|
||||
if (this->mainWindow != nullptr) {
|
||||
this->mainWindow->update();
|
||||
}
|
||||
}
|
||||
// void WindowManager::updateAll()
|
||||
//{
|
||||
// if (this->mainWindow != nullptr) {
|
||||
// this->mainWindow->update();
|
||||
// }
|
||||
//}
|
||||
|
||||
widgets::MainWindow &WindowManager::getMainWindow()
|
||||
{
|
||||
|
|
|
@ -23,7 +23,7 @@ public:
|
|||
void layoutVisibleChatWidgets(Channel *channel = nullptr);
|
||||
void repaintVisibleChatWidgets(Channel *channel = nullptr);
|
||||
void repaintGifEmotes();
|
||||
void updateAll();
|
||||
// void updateAll();
|
||||
|
||||
widgets::MainWindow &getMainWindow();
|
||||
|
||||
|
|
Loading…
Reference in a new issue