From c719bb6b74ff2463c935d767ec6246c0ca66b304 Mon Sep 17 00:00:00 2001 From: fourtf Date: Sat, 11 Aug 2018 14:20:53 +0200 Subject: [PATCH] categorized emtotepopup --- chatterino.pro | 9 +- src/Application.cpp | 4 +- src/common/{MutexValue.hpp => Atomic.hpp} | 13 +- src/common/CompletionModel.cpp | 2 +- src/common/NetworkRequest.cpp | 15 +- src/common/NetworkResult.cpp | 2 +- src/common/SimpleSignalVector.hpp | 34 --- src/common/UniqueAccess.hpp | 7 +- .../commands/CommandController.cpp | 2 +- src/debug/Benchmark.cpp | 21 ++ src/debug/Benchmark.hpp | 32 +-- src/debug/Log.hpp | 13 +- src/main.cpp | 6 +- src/messages/Emote.cpp | 62 +----- src/messages/Emote.hpp | 2 + src/messages/EmoteMap.cpp | 44 ---- src/messages/EmoteMap.hpp | 20 -- src/messages/Image.cpp | 6 +- src/messages/MessageBuilder.hpp | 8 + src/messages/MessageParseArgs.hpp | 7 - src/messages/Selection.hpp | 2 +- src/messages/layouts/MessageLayout.hpp | 3 - .../layouts/MessageLayoutContainer.cpp | 7 +- src/providers/bttv/BttvEmotes.cpp | 115 ++++------ src/providers/bttv/BttvEmotes.hpp | 22 +- src/providers/emoji/Emojis.cpp | 6 +- src/providers/emoji/Emojis.hpp | 1 - src/providers/ffz/FfzEmotes.cpp | 96 ++++----- src/providers/ffz/FfzEmotes.hpp | 25 +-- src/providers/irc/AbstractIrcServer.cpp | 2 +- src/providers/twitch/IrcMessageHandler.cpp | 8 +- src/providers/twitch/PartialTwitchUser.cpp | 8 +- src/providers/twitch/PubsubClient.cpp | 80 +++---- src/providers/twitch/PubsubHelpers.hpp | 4 +- src/providers/twitch/TwitchAccount.cpp | 35 ++- src/providers/twitch/TwitchAccount.hpp | 1 + src/providers/twitch/TwitchAccountManager.cpp | 12 +- src/providers/twitch/TwitchApi.cpp | 8 +- src/providers/twitch/TwitchChannel.cpp | 18 +- src/providers/twitch/TwitchChannel.hpp | 2 +- src/providers/twitch/TwitchHelpers.cpp | 2 +- src/providers/twitch/TwitchMessageBuilder.cpp | 12 +- src/providers/twitch/TwitchMessageBuilder.hpp | 1 - src/providers/twitch/TwitchServer.hpp | 4 +- src/singletons/Emotes.cpp | 4 +- src/singletons/Settings.cpp | 6 +- src/singletons/WindowManager.cpp | 2 +- src/singletons/helper/LoggingChannel.cpp | 4 +- src/util/Helpers.hpp | 2 +- src/widgets/dialogs/EmotePopup.cpp | 200 +++++++++--------- src/widgets/dialogs/EmotePopup.hpp | 6 +- src/widgets/dialogs/QualityPopup.cpp | 2 +- src/widgets/helper/ChannelView.cpp | 11 +- src/widgets/settingspages/AboutPage.cpp | 2 +- src/widgets/splits/Split.cpp | 2 +- 55 files changed, 420 insertions(+), 604 deletions(-) rename src/common/{MutexValue.hpp => Atomic.hpp} (66%) delete mode 100644 src/common/SimpleSignalVector.hpp create mode 100644 src/debug/Benchmark.cpp delete mode 100644 src/messages/EmoteMap.cpp delete mode 100644 src/messages/EmoteMap.hpp diff --git a/chatterino.pro b/chatterino.pro index a7ff626a6..7ddf1fd34 100644 --- a/chatterino.pro +++ b/chatterino.pro @@ -233,7 +233,6 @@ SOURCES += \ src/providers/twitch/PubsubClient.cpp \ src/providers/twitch/TwitchApi.cpp \ src/messages/Emote.cpp \ - src/messages/EmoteMap.cpp \ src/messages/ImageSet.cpp \ src/providers/bttv/BttvEmotes.cpp \ src/providers/ffz/FfzEmotes.cpp \ @@ -250,7 +249,8 @@ SOURCES += \ src/util/FunctionEventFilter.cpp \ src/widgets/helper/EffectLabel.cpp \ src/widgets/helper/Button.cpp \ - src/messages/MessageContainer.cpp + src/messages/MessageContainer.cpp \ + src/debug/Benchmark.cpp HEADERS += \ src/Application.hpp \ @@ -258,7 +258,7 @@ HEADERS += \ src/common/Common.hpp \ src/common/CompletionModel.hpp \ src/common/FlagsEnum.hpp \ - src/common/MutexValue.hpp \ + src/common/Atomic.hpp \ src/common/NetworkCommon.hpp \ src/common/NetworkData.hpp \ src/common/NetworkManager.hpp \ @@ -305,7 +305,6 @@ HEADERS += \ src/messages/MessageBuilder.hpp \ src/messages/MessageColor.hpp \ src/messages/MessageElement.hpp \ - src/messages/MessageParseArgs.hpp \ src/messages/Selection.hpp \ src/PrecompiledHeader.hpp \ src/providers/emoji/Emojis.hpp \ @@ -414,7 +413,6 @@ HEADERS += \ src/singletons/Updates.hpp \ src/singletons/NativeMessaging.hpp \ src/singletons/Theme.hpp \ - src/common/SimpleSignalVector.hpp \ src/common/SignalVector.hpp \ src/widgets/dialogs/LogsPopup.hpp \ src/common/Singleton.hpp \ @@ -427,7 +425,6 @@ HEADERS += \ src/providers/twitch/PubsubClient.hpp \ src/providers/twitch/TwitchApi.hpp \ src/messages/Emote.hpp \ - src/messages/EmoteMap.hpp \ src/messages/EmoteCache.hpp \ src/messages/ImageSet.hpp \ src/common/Outcome.hpp \ diff --git a/src/Application.cpp b/src/Application.cpp index c912597c8..85b4f382c 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -113,11 +113,11 @@ void Application::initNm() void Application::initPubsub() { this->twitch.pubsub->signals_.whisper.sent.connect([](const auto &msg) { - Log("WHISPER SENT LOL"); // + log("WHISPER SENT LOL"); // }); this->twitch.pubsub->signals_.whisper.received.connect([](const auto &msg) { - Log("WHISPER RECEIVED LOL"); // + log("WHISPER RECEIVED LOL"); // }); this->twitch.pubsub->signals_.moderation.chatCleared.connect( diff --git a/src/common/MutexValue.hpp b/src/common/Atomic.hpp similarity index 66% rename from src/common/MutexValue.hpp rename to src/common/Atomic.hpp index 112257370..39d8119f6 100644 --- a/src/common/MutexValue.hpp +++ b/src/common/Atomic.hpp @@ -6,14 +6,14 @@ namespace chatterino { template -class MutexValue : boost::noncopyable +class Atomic : boost::noncopyable { public: - MutexValue() + Atomic() { } - MutexValue(T &&val) + Atomic(T &&val) : value_(val) { } @@ -32,6 +32,13 @@ public: this->value_ = val; } + void set(T &&val) + { + std::lock_guard guard(this->mutex_); + + this->value_ = std::move(val); + } + private: mutable std::mutex mutex_; T value_; diff --git a/src/common/CompletionModel.cpp b/src/common/CompletionModel.cpp index bd0038107..f6dfd5b0c 100644 --- a/src/common/CompletionModel.cpp +++ b/src/common/CompletionModel.cpp @@ -104,7 +104,7 @@ int CompletionModel::rowCount(const QModelIndex &) const void CompletionModel::refresh() { - Log("[CompletionModel:{}] Refreshing...]", this->channelName_); + log("[CompletionModel:{}] Refreshing...]", this->channelName_); auto app = getApp(); diff --git a/src/common/NetworkRequest.cpp b/src/common/NetworkRequest.cpp index f7a288206..f54192190 100644 --- a/src/common/NetworkRequest.cpp +++ b/src/common/NetworkRequest.cpp @@ -136,7 +136,7 @@ void NetworkRequest::execute() } break; default: { - Log("[Execute] Unhandled request type"); + log("[Execute] Unhandled request type"); } break; } } @@ -190,10 +190,11 @@ void NetworkRequest::doRequest() case NetworkRequestType::Put: return NetworkManager::accessManager.put(data->request_, - data->payload_); + data->payload_); case NetworkRequestType::Delete: - return NetworkManager::accessManager.deleteResource(data->request_); + return NetworkManager::accessManager.deleteResource( + data->request_); default: return nullptr; @@ -201,13 +202,13 @@ void NetworkRequest::doRequest() }(); if (reply == nullptr) { - Log("Unhandled request type"); + log("Unhandled request type"); return; } if (timer->isStarted()) { timer->onTimeout(worker, [reply, data]() { - Log("Aborted!"); + log("Aborted!"); reply->abort(); if (data->onError_) { data->onError_(-2); @@ -234,7 +235,7 @@ void NetworkRequest::doRequest() NetworkResult result(bytes); DebugCount::increase("http request success"); - Log("starting {}", data->request_.url().toString()); + // log("starting {}", data->request_.url().toString()); if (data->onSuccess_) { if (data->executeConcurrently) QtConcurrent::run( @@ -243,7 +244,7 @@ void NetworkRequest::doRequest() else data->onSuccess_(result); } - Log("finished {}", data->request_.url().toString()); + // log("finished {}", data->request_.url().toString()); reply->deleteLater(); }; diff --git a/src/common/NetworkResult.cpp b/src/common/NetworkResult.cpp index 443d0aa05..78884a421 100644 --- a/src/common/NetworkResult.cpp +++ b/src/common/NetworkResult.cpp @@ -31,7 +31,7 @@ rapidjson::Document NetworkResult::parseRapidJson() const ret.Parse(this->data_.data(), this->data_.length()); if (result.Code() != rapidjson::kParseErrorNone) { - Log("JSON parse error: {} ({})", + log("JSON parse error: {} ({})", rapidjson::GetParseError_En(result.Code()), result.Offset()); return ret; } diff --git a/src/common/SimpleSignalVector.hpp b/src/common/SimpleSignalVector.hpp deleted file mode 100644 index 6aca458f5..000000000 --- a/src/common/SimpleSignalVector.hpp +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include - -#include -#include - -namespace chatterino { - -template -class SimpleSignalVector -{ -public: - SimpleSignalVector &operator=(std::vector &other) - { - this->data_ = other; - - this->updated.invoke(); - - return *this; - } - - operator std::vector &() - { - return this->data_; - } - - pajlada::Signals::NoArgSignal updated; - -private: - std::vector data_; -}; - -} // namespace chatterino diff --git a/src/common/UniqueAccess.hpp b/src/common/UniqueAccess.hpp index 6e9f7a52e..30d6bee32 100644 --- a/src/common/UniqueAccess.hpp +++ b/src/common/UniqueAccess.hpp @@ -46,16 +46,15 @@ public: } private: - T *element_; - std::mutex *mutex_; - bool isValid_ = true; + T *element_{}; + std::mutex *mutex_{}; + bool isValid_{true}; }; template class UniqueAccess { public: - // template UniqueAccess() : element_(T()) { diff --git a/src/controllers/commands/CommandController.cpp b/src/controllers/commands/CommandController.cpp index 111c06786..3aaefca8b 100644 --- a/src/controllers/commands/CommandController.cpp +++ b/src/controllers/commands/CommandController.cpp @@ -78,7 +78,7 @@ void CommandController::save() { QFile textFile(this->filePath_); if (!textFile.open(QIODevice::WriteOnly)) { - Log("[CommandController::saveCommands] Unable to open {} for writing", + log("[CommandController::saveCommands] Unable to open {} for writing", this->filePath_); return; } diff --git a/src/debug/Benchmark.cpp b/src/debug/Benchmark.cpp new file mode 100644 index 000000000..2ab28a680 --- /dev/null +++ b/src/debug/Benchmark.cpp @@ -0,0 +1,21 @@ +#include "Benchmark.hpp" + +namespace chatterino { + +BenchmarkGuard::BenchmarkGuard(const QString &_name) + : name_(_name) +{ + timer_.start(); +} + +BenchmarkGuard::~BenchmarkGuard() +{ + log("{} {} ms", this->name_, float(timer_.nsecsElapsed()) / 1000000.0f); +} + +qreal BenchmarkGuard::getElapsedMs() +{ + return qreal(timer_.nsecsElapsed()) / 1000000.0; +} + +} // namespace chatterino diff --git a/src/debug/Benchmark.hpp b/src/debug/Benchmark.hpp index 5faa1a537..065048e8f 100644 --- a/src/debug/Benchmark.hpp +++ b/src/debug/Benchmark.hpp @@ -3,40 +3,20 @@ #include "debug/Log.hpp" #include -#include #include -#define BENCH(x) \ - QElapsedTimer x; \ - x.start(); - -#define MARK(x) \ - qDebug() << BOOST_CURRENT_FUNCTION << __LINE__ \ - << static_cast(x.nsecsElapsed()) / 1000000.0 << "ms"; - namespace chatterino { class BenchmarkGuard : boost::noncopyable { - QElapsedTimer timer; - QString name; - public: - BenchmarkGuard(const QString &_name) - : name(_name) - { - timer.start(); - } + BenchmarkGuard(const QString &_name); + ~BenchmarkGuard(); + qreal getElapsedMs(); - ~BenchmarkGuard() - { - Log("{} {} ms", this->name, float(timer.nsecsElapsed()) / 1000000.0f); - } - - qreal getElapsedMs() - { - return qreal(timer.nsecsElapsed()) / 1000000.0; - } +private: + QElapsedTimer timer_; + QString name_; }; } // namespace chatterino diff --git a/src/debug/Log.hpp b/src/debug/Log.hpp index 51ef0f053..31536781a 100644 --- a/src/debug/Log.hpp +++ b/src/debug/Log.hpp @@ -8,17 +8,22 @@ namespace chatterino { template -inline void Log(const std::string &formatString, Args &&... args) +inline void log(const std::string &formatString, Args &&... args) { qDebug().noquote() << QTime::currentTime().toString("hh:mm:ss.zzz") << fS(formatString, std::forward(args)...).c_str(); } template -inline void Warn(const std::string &formatString, Args &&... args) +inline void log(const char *formatString, Args &&... args) { - qWarning() << QTime::currentTime().toString("hh:mm:ss.zzz") - << fS(formatString, std::forward(args)...).c_str(); + log(std::string(formatString), std::forward(args)...); +} + +template +inline void log(const QString &formatString, Args &&... args) +{ + log(formatString.toStdString(), std::forward(args)...); } } // namespace chatterino diff --git a/src/main.cpp b/src/main.cpp index 5f259a8be..4bf6e7daf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,13 +5,15 @@ #include #include - -#include +#include using namespace chatterino; int main(int argc, char **argv) { + auto shared = std::make_shared(); + log(std::atomic_is_lock_free(&shared)); + QApplication a(argc, argv); // convert char** to QStringList diff --git a/src/messages/Emote.cpp b/src/messages/Emote.cpp index 369725426..c5ff83e12 100644 --- a/src/messages/Emote.cpp +++ b/src/messages/Emote.cpp @@ -15,61 +15,13 @@ bool operator!=(const Emote &a, const Emote &b) return !(a == b); } -// EmotePtr Emote::create(const EmoteData2 &data) -//{ -//} +EmotePtr cachedOrMakeEmotePtr(Emote &&emote, const EmoteMap &cache) +{ + // reuse old shared_ptr if nothing changed + auto it = cache.find(emote.name); + if (it != cache.end() && *it->second == emote) return it->second; -// EmotePtr Emote::create(EmoteData2 &&data) -//{ -//} - -// Emote::Emote(EmoteData2 &&data) -// : data_(data) -//{ -//} -// -// Emote::Emote(const EmoteData2 &data) -// : data_(data) -//{ -//} -// -// const Url &Emote::getHomePage() const -//{ -// return this->data_.homePage; -//} -// -// const EmoteName &Emote::getName() const -//{ -// return this->data_.name; -//} -// -// const Tooltip &Emote::getTooltip() const -//{ -// return this->data_.tooltip; -//} -// -// const ImageSet &Emote::getImages() const -//{ -// return this->data_.images; -//} -// -// const QString &Emote::getCopyString() const -//{ -// return this->data_.name.string; -//} -// -// bool Emote::operator==(const Emote &other) const -//{ -// auto &a = this->data_; -// auto &b = other.data_; -// -// return std::tie(a.homePage, a.name, a.tooltip, a.images) == -// std::tie(b.homePage, b.name, b.tooltip, b.images); -//} -// -// bool Emote::operator!=(const Emote &other) const -//{ -// return !this->operator==(other); -//} + return std::make_shared(std::move(emote)); +} } // namespace chatterino diff --git a/src/messages/Emote.hpp b/src/messages/Emote.hpp index 9c7b5f680..cfde58492 100644 --- a/src/messages/Emote.hpp +++ b/src/messages/Emote.hpp @@ -37,4 +37,6 @@ using EmoteIdMap = std::unordered_map; using WeakEmoteMap = std::unordered_map>; using WeakEmoteIdMap = std::unordered_map>; +EmotePtr cachedOrMakeEmotePtr(Emote &&emote, const EmoteMap &cache); + } // namespace chatterino diff --git a/src/messages/EmoteMap.cpp b/src/messages/EmoteMap.cpp deleted file mode 100644 index f940de852..000000000 --- a/src/messages/EmoteMap.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "EmoteMap.hpp" - -#include "Application.hpp" -#include "singletons/Settings.hpp" - -namespace chatterino { - -// EmoteData::EmoteData(Image *image) -// : image1x(image) -//{ -//} - -//// Emotes must have a 1x image to be valid -// bool EmoteData::isValid() const -//{ -// return this->image1x != nullptr; -//} - -// Image *EmoteData::getImage(float scale) const -//{ -// int quality = getApp()->settings->preferredEmoteQuality; - -// if (quality == 0) { -// scale *= getApp()->settings->emoteScale.getValue(); -// quality = [&] { -// if (scale <= 1) return 1; -// if (scale <= 2) return 2; -// return 3; -// }(); -// } - -// Image *_image; -// if (quality == 3 && this->image3x != nullptr) { -// _image = this->image3x; -// } else if (quality >= 2 && this->image2x != nullptr) { -// _image = this->image2x; -// } else { -// _image = this->image1x; -// } - -// return _image; -//} - -} // namespace chatterino diff --git a/src/messages/EmoteMap.hpp b/src/messages/EmoteMap.hpp deleted file mode 100644 index 30a0dfdd1..000000000 --- a/src/messages/EmoteMap.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "boost/optional.hpp" -#include "messages/Emote.hpp" - -namespace chatterino { - -// class EmoteMap -//{ -// public: -// void add(Emote emote); -// void remove(const Emote &emote); -// void remove(const QString &name); - -// private: -//}; - -// using EmoteMap = ConcurrentMap; - -} // namespace chatterino diff --git a/src/messages/Image.cpp b/src/messages/Image.cpp index 29b093f36..56286cdfe 100644 --- a/src/messages/Image.cpp +++ b/src/messages/Image.cpp @@ -78,7 +78,7 @@ QVector> readFrames(QImageReader &reader, const Url &url) QVector> frames; if (reader.imageCount() == 0) { - Log("Error while reading image {}: '{}'", url.string, + log("Error while reading image {}: '{}'", url.string, reader.errorString()); return frames; } @@ -94,7 +94,7 @@ QVector> readFrames(QImageReader &reader, const Url &url) } if (frames.size() == 0) { - Log("Error while reading image {}: '{}'", url.string, + log("Error while reading image {}: '{}'", url.string, reader.errorString()); } @@ -200,7 +200,7 @@ Image::Image(const Url &url, qreal scale) Image::Image(const QPixmap &pixmap, qreal scale) : scale_(scale) - , frames_(QVector>{Frame{pixmap}}) + , frames_(QVector>{Frame{pixmap, 1}}) { } diff --git a/src/messages/MessageBuilder.hpp b/src/messages/MessageBuilder.hpp index 5ae197254..a2e78ec29 100644 --- a/src/messages/MessageBuilder.hpp +++ b/src/messages/MessageBuilder.hpp @@ -16,6 +16,14 @@ const TimeoutMessageTag timeoutMessage{}; MessagePtr makeSystemMessage(const QString &text); +struct MessageParseArgs { + bool disablePingSounds = false; + bool isReceivedWhisper = false; + bool isSentWhisper = false; + bool trimSubscriberUsername = false; + bool isStaffOrBroadcaster = false; +}; + class MessageBuilder { public: diff --git a/src/messages/MessageParseArgs.hpp b/src/messages/MessageParseArgs.hpp index f3d732c4b..519262dc1 100644 --- a/src/messages/MessageParseArgs.hpp +++ b/src/messages/MessageParseArgs.hpp @@ -2,12 +2,5 @@ namespace chatterino { -struct MessageParseArgs { - bool disablePingSounds = false; - bool isReceivedWhisper = false; - bool isSentWhisper = false; - bool trimSubscriberUsername = false; - bool isStaffOrBroadcaster = false; -}; } // namespace chatterino diff --git a/src/messages/Selection.hpp b/src/messages/Selection.hpp index dbed15d30..8eefc3a33 100644 --- a/src/messages/Selection.hpp +++ b/src/messages/Selection.hpp @@ -35,7 +35,7 @@ struct SelectionItem { bool operator>(const SelectionItem &b) const { - return b.operator<(*this); + return this->operator!=(b) && b.operator<(*this); } bool operator==(const SelectionItem &b) const diff --git a/src/messages/layouts/MessageLayout.hpp b/src/messages/layouts/MessageLayout.hpp index 629da9685..0f0d5cab3 100644 --- a/src/messages/layouts/MessageLayout.hpp +++ b/src/messages/layouts/MessageLayout.hpp @@ -31,13 +31,10 @@ public: const Message *getMessage(); - // Height int getHeight() const; - // Flags MessageLayoutFlags flags; - // Layout bool layout(int width, float scale_, MessageElementFlags flags); // Painting diff --git a/src/messages/layouts/MessageLayoutContainer.cpp b/src/messages/layouts/MessageLayoutContainer.cpp index 5e6350433..699cfc604 100644 --- a/src/messages/layouts/MessageLayoutContainer.cpp +++ b/src/messages/layouts/MessageLayoutContainer.cpp @@ -126,9 +126,10 @@ void MessageLayoutContainer::breakLine() int xOffset = 0; if (this->flags_.has(MessageFlag::Centered) && this->elements_.size() > 0) { - xOffset = (width_ - this->elements_.at(this->elements_.size() - 1) - ->getRect() - .right()) / + xOffset = (width_ - this->elements_.at(0)->getRect().left() - + this->elements_.at(this->elements_.size() - 1) + ->getRect() + .right()) / 2; } diff --git a/src/providers/bttv/BttvEmotes.cpp b/src/providers/bttv/BttvEmotes.cpp index b9ca7ba99..072212c21 100644 --- a/src/providers/bttv/BttvEmotes.cpp +++ b/src/providers/bttv/BttvEmotes.cpp @@ -10,9 +10,7 @@ #include namespace chatterino { - namespace { - Url getEmoteLink(QString urlTemplate, const EmoteId &id, const QString &emoteScale) { @@ -21,72 +19,14 @@ Url getEmoteLink(QString urlTemplate, const EmoteId &id, return {urlTemplate.replace("{{id}}", id.string) .replace("{{image}}", emoteScale)}; } - -} // namespace - -AccessGuard BttvEmotes::accessGlobalEmotes() const -{ - return this->globalEmotes_.accessConst(); -} - -boost::optional BttvEmotes::getGlobalEmote(const EmoteName &name) -{ - auto emotes = this->globalEmotes_.access(); - auto it = emotes->find(name); - - if (it == emotes->end()) return boost::none; - return it->second; -} - -// FOURTF: never returns anything -// boost::optional BttvEmotes::getEmote(const EmoteId &id) -//{ -// auto cache = this->channelEmoteCache_.access(); -// auto it = cache->find(id); -// -// if (it != cache->end()) { -// auto shared = it->second.lock(); -// if (shared) { -// return shared; -// } -// } -// -// return boost::none; -//} - -void BttvEmotes::loadGlobalEmotes() -{ - auto request = NetworkRequest(QString(globalEmoteApiUrl)); - - request.setCaller(QThread::currentThread()); - request.setTimeout(30000); - request.onSuccess([this](auto result) -> Outcome { - // if (auto shared = weak.lock()) { - auto currentEmotes = this->globalEmotes_.access(); - - auto pair = this->parseGlobalEmotes(result.parseJson(), *currentEmotes); - - if (pair.first) { - *currentEmotes = std::move(pair.second); - } - - return pair.first; - // } - return Failure; - }); - - request.execute(); -} - -std::pair BttvEmotes::parseGlobalEmotes( - const QJsonObject &jsonRoot, const EmoteMap ¤tEmotes) +std::pair parseGlobalEmotes(const QJsonObject &jsonRoot, + const EmoteMap ¤tEmotes) { auto emotes = EmoteMap(); auto jsonEmotes = jsonRoot.value("emotes").toArray(); - auto urlTemplate = - QString("https:" + jsonRoot.value("urlTemplate").toString()); + auto urlTemplate = qS("https:") + jsonRoot.value("urlTemplate").toString(); - for (const QJsonValue &jsonEmote : jsonEmotes) { + for (auto jsonEmote : jsonEmotes) { auto id = EmoteId{jsonEmote.toObject().value("id").toString()}; auto name = EmoteName{jsonEmote.toObject().value("code").toString()}; @@ -99,16 +39,49 @@ std::pair BttvEmotes::parseGlobalEmotes( Tooltip{name.string + "
Global Bttv Emote"}, Url{"https://manage.betterttv.net/emotes/" + id.string}}); - auto it = currentEmotes.find(name); - if (it != currentEmotes.end() && *it->second == emote) { - // reuse old shared_ptr if nothing changed - emotes[name] = it->second; - } else { - emotes[name] = std::make_shared(std::move(emote)); - } + emotes[name] = cachedOrMakeEmotePtr(std::move(emote), currentEmotes); } return {Success, std::move(emotes)}; } +} // namespace + +BttvEmotes::BttvEmotes() + : global_(std::make_shared()) +{ +} + +std::shared_ptr BttvEmotes::global() const +{ + return this->global_.get(); +} + +boost::optional BttvEmotes::global(const EmoteName &name) const +{ + auto emotes = this->global_.get(); + auto it = emotes->find(name); + + if (it == emotes->end()) return boost::none; + return it->second; +} + +void BttvEmotes::loadGlobal() +{ + auto request = NetworkRequest(QString(globalEmoteApiUrl)); + + request.setCaller(QThread::currentThread()); + request.setTimeout(30000); + + request.onSuccess([this](auto result) -> Outcome { + auto emotes = this->global_.get(); + auto pair = parseGlobalEmotes(result.parseJson(), *emotes); + if (pair.first) + this->global_.set( + std::make_shared(std::move(pair.second))); + return pair.first; + }); + + request.execute(); +} } // namespace chatterino diff --git a/src/providers/bttv/BttvEmotes.hpp b/src/providers/bttv/BttvEmotes.hpp index f85333df7..510f873fc 100644 --- a/src/providers/bttv/BttvEmotes.hpp +++ b/src/providers/bttv/BttvEmotes.hpp @@ -1,33 +1,25 @@ #pragma once #include - -#include "common/UniqueAccess.hpp" +#include "common/Atomic.hpp" #include "messages/Emote.hpp" -#include "messages/EmoteCache.hpp" namespace chatterino { -class BttvEmotes final : std::enable_shared_from_this +class BttvEmotes final { static constexpr const char *globalEmoteApiUrl = "https://api.betterttv.net/2/emotes"; public: - // BttvEmotes(); + BttvEmotes(); - AccessGuard accessGlobalEmotes() const; - boost::optional getGlobalEmote(const EmoteName &name); - boost::optional getEmote(const EmoteId &id); - - void loadGlobalEmotes(); + std::shared_ptr global() const; + boost::optional global(const EmoteName &name) const; + void loadGlobal(); private: - std::pair parseGlobalEmotes( - const QJsonObject &jsonRoot, const EmoteMap ¤tEmotes); - - UniqueAccess globalEmotes_; - // UniqueAccess channelEmoteCache_; + Atomic> global_; }; } // namespace chatterino diff --git a/src/providers/emoji/Emojis.cpp b/src/providers/emoji/Emojis.cpp index ec7bac2b8..06d4e798b 100644 --- a/src/providers/emoji/Emojis.cpp +++ b/src/providers/emoji/Emojis.cpp @@ -118,7 +118,7 @@ void Emojis::loadEmojis() rapidjson::ParseResult result = root.Parse(data.toUtf8(), data.length()); if (result.Code() != rapidjson::kParseErrorNone) { - Log("JSON parse error: {} ({})", + log("JSON parse error: {} ({})", rapidjson::GetParseError_En(result.Code()), result.Offset()); return; } @@ -146,7 +146,7 @@ void Emojis::loadEmojis() auto toneNameIt = toneNames.find(tone); if (toneNameIt == toneNames.end()) { - Log("Tone with key {} does not exist in tone names map", + log("Tone with key {} does not exist in tone names map", tone); continue; } @@ -219,7 +219,7 @@ void Emojis::loadEmojiSet() auto app = getApp(); app->settings->emojiSet.connect([=](const auto &emojiSet, auto) { - Log("Using emoji set {}", emojiSet); + log("Using emoji set {}", emojiSet); this->emojis.each([=](const auto &name, std::shared_ptr &emoji) { QString emojiSetToUse = emojiSet; diff --git a/src/providers/emoji/Emojis.hpp b/src/providers/emoji/Emojis.hpp index c4ff69bbe..18bd33522 100644 --- a/src/providers/emoji/Emojis.hpp +++ b/src/providers/emoji/Emojis.hpp @@ -1,6 +1,5 @@ #pragma once -#include "common/SimpleSignalVector.hpp" #include "messages/Emote.hpp" #include "util/ConcurrentMap.hpp" diff --git a/src/providers/ffz/FfzEmotes.cpp b/src/providers/ffz/FfzEmotes.cpp index b5fe65aa2..be6d776c6 100644 --- a/src/providers/ffz/FfzEmotes.cpp +++ b/src/providers/ffz/FfzEmotes.cpp @@ -19,7 +19,6 @@ Url getEmoteLink(const QJsonObject &urls, const QString &emoteScale) return {"https:" + emote.toString()}; } - void fillInEmoteData(const QJsonObject &urls, const EmoteName &name, const QString &tooltip, Emote &emoteData) { @@ -34,52 +33,11 @@ void fillInEmoteData(const QJsonObject &urls, const EmoteName &name, Image::fromUrl(url3x, 0.25)}; emoteData.tooltip = {tooltip}; } -} // namespace - -AccessGuard> FfzEmotes::accessGlobalEmotes() const -{ - return this->globalEmotes_.accessConst(); -} - -boost::optional FfzEmotes::getEmote(const EmoteId &id) -{ - auto cache = this->channelEmoteCache_.access(); - auto it = cache->find(id); - - if (it != cache->end()) { - auto shared = it->second.lock(); - if (shared) { - return shared; - } - } - - return boost::none; -} - -boost::optional FfzEmotes::getGlobalEmote(const EmoteName &name) -{ - return this->globalEmotes_.access()->get(name); -} - -void FfzEmotes::loadGlobalEmotes() -{ - QString url("https://api.frankerfacez.com/v1/set/global"); - - NetworkRequest request(url); - request.setCaller(QThread::currentThread()); - request.setTimeout(30000); - request.onSuccess([this](auto result) -> Outcome { - return this->parseGlobalEmotes(result.parseJson()); - }); - - request.execute(); -} - -Outcome FfzEmotes::parseGlobalEmotes(const QJsonObject &jsonRoot) +std::pair parseGlobalEmotes(const QJsonObject &jsonRoot, + const EmoteMap ¤tEmotes) { auto jsonSets = jsonRoot.value("sets").toObject(); - auto emotes = this->globalEmotes_.access(); - auto replacement = emotes->makeReplacment(); + auto emotes = EmoteMap(); for (auto jsonSet : jsonSets) { auto jsonEmotes = jsonSet.toObject().value("emoticons").toArray(); @@ -99,15 +57,55 @@ Outcome FfzEmotes::parseGlobalEmotes(const QJsonObject &jsonRoot) .arg(id.string) .arg(name.string)}; - replacement.add(name, emote); + emotes[name] = + cachedOrMakeEmotePtr(std::move(emote), currentEmotes); } } - return Success; + return {Success, std::move(emotes)}; +} +} // namespace + +FfzEmotes::FfzEmotes() + : global_(std::make_shared()) +{ } -void FfzEmotes::loadChannelEmotes(const QString &channelName, - std::function callback) +std::shared_ptr FfzEmotes::global() const +{ + return this->global_.get(); +} + +boost::optional FfzEmotes::global(const EmoteName &name) const +{ + auto emotes = this->global_.get(); + auto it = emotes->find(name); + if (it != emotes->end()) return it->second; + return boost::none; +} + +void FfzEmotes::loadGlobal() +{ + QString url("https://api.frankerfacez.com/v1/set/global"); + + NetworkRequest request(url); + request.setCaller(QThread::currentThread()); + request.setTimeout(30000); + + request.onSuccess([this](auto result) -> Outcome { + auto emotes = this->global(); + auto pair = parseGlobalEmotes(result.parseJson(), *emotes); + if (pair.first) + this->global_.set( + std::make_shared(std::move(pair.second))); + return pair.first; + }); + + request.execute(); +} + +void FfzEmotes::loadChannel(const QString &channelName, + std::function callback) { // printf("[FFZEmotes] Reload FFZ Channel Emotes for channel %s\n", // qPrintable(channelName)); diff --git a/src/providers/ffz/FfzEmotes.hpp b/src/providers/ffz/FfzEmotes.hpp index 2dd747e02..ccc850bff 100644 --- a/src/providers/ffz/FfzEmotes.hpp +++ b/src/providers/ffz/FfzEmotes.hpp @@ -2,7 +2,7 @@ #include -#include "common/UniqueAccess.hpp" +#include "common/Atomic.hpp" #include "messages/Emote.hpp" #include "messages/EmoteCache.hpp" @@ -16,24 +16,17 @@ class FfzEmotes final : std::enable_shared_from_this "https://api.betterttv.net/2/channels/"; public: - // FfzEmotes(); + FfzEmotes(); - static std::shared_ptr create(); + std::shared_ptr global() const; + boost::optional global(const EmoteName &name) const; - AccessGuard> accessGlobalEmotes() const; - boost::optional getGlobalEmote(const EmoteName &name); - boost::optional getEmote(const EmoteId &id); + void loadGlobal(); + void loadChannel(const QString &channelName, + std::function callback); - void loadGlobalEmotes(); - void loadChannelEmotes(const QString &channelName, - std::function callback); - -protected: - Outcome parseGlobalEmotes(const QJsonObject &jsonRoot); - Outcome parseChannelEmotes(const QJsonObject &jsonRoot); - - UniqueAccess> globalEmotes_; - UniqueAccess channelEmoteCache_; +private: + Atomic> global_; }; } // namespace chatterino diff --git a/src/providers/irc/AbstractIrcServer.cpp b/src/providers/irc/AbstractIrcServer.cpp index 23bf47d26..b7995282f 100644 --- a/src/providers/irc/AbstractIrcServer.cpp +++ b/src/providers/irc/AbstractIrcServer.cpp @@ -131,7 +131,7 @@ std::shared_ptr AbstractIrcServer::getOrAddChannel( chan->destroyed.connect([this, clojuresInCppAreShit] { // fourtf: issues when the server itself is destroyed - Log("[AbstractIrcServer::addChannel] {} was destroyed", + log("[AbstractIrcServer::addChannel] {} was destroyed", clojuresInCppAreShit); this->channels.remove(clojuresInCppAreShit); diff --git a/src/providers/twitch/IrcMessageHandler.cpp b/src/providers/twitch/IrcMessageHandler.cpp index 5d628e311..35c7c51d9 100644 --- a/src/providers/twitch/IrcMessageHandler.cpp +++ b/src/providers/twitch/IrcMessageHandler.cpp @@ -145,7 +145,7 @@ void IrcMessageHandler::handleClearChatMessage(Communi::IrcMessage *message) auto chan = app->twitch.server->getChannelOrEmpty(chanName); if (chan->isEmpty()) { - Log("[IrcMessageHandler:handleClearChatMessage] Twitch channel {} not " + log("[IrcMessageHandler:handleClearChatMessage] Twitch channel {} not " "found", chanName); return; @@ -209,7 +209,7 @@ void IrcMessageHandler::handleUserStateMessage(Communi::IrcMessage *message) void IrcMessageHandler::handleWhisperMessage(Communi::IrcMessage *message) { auto app = getApp(); - Log("Received whisper!"); + log("Received whisper!"); MessageParseArgs args; args.isReceivedWhisper = true; @@ -326,7 +326,7 @@ void IrcMessageHandler::handleNoticeMessage(Communi::IrcNoticeMessage *message) auto channel = app->twitch.server->getChannelOrEmpty(channelName); if (channel->isEmpty()) { - Log("[IrcManager:handleNoticeMessage] Channel {} not found in channel " + log("[IrcManager:handleNoticeMessage] Channel {} not found in channel " "manager ", channelName); return; @@ -366,7 +366,7 @@ void IrcMessageHandler::handleWriteConnectionNoticeMessage( return; } - Log("Showing notice message from write connection with message id '{}'", + log("Showing notice message from write connection with message id '{}'", msgID); } diff --git a/src/providers/twitch/PartialTwitchUser.cpp b/src/providers/twitch/PartialTwitchUser.cpp index 98fa2ba42..c3d9e5102 100644 --- a/src/providers/twitch/PartialTwitchUser.cpp +++ b/src/providers/twitch/PartialTwitchUser.cpp @@ -42,23 +42,23 @@ void PartialTwitchUser::getId(std::function successCallback, request.onSuccess([successCallback](auto result) -> Outcome { auto root = result.parseJson(); if (!root.value("users").isArray()) { - Log("API Error while getting user id, users is not an array"); + log("API Error while getting user id, users is not an array"); return Failure; } auto users = root.value("users").toArray(); if (users.size() != 1) { - Log("API Error while getting user id, users array size is not 1"); + log("API Error while getting user id, users array size is not 1"); return Failure; } if (!users[0].isObject()) { - Log("API Error while getting user id, first user is not an object"); + log("API Error while getting user id, first user is not an object"); return Failure; } auto firstUser = users[0].toObject(); auto id = firstUser.value("_id"); if (!id.isString()) { - Log("API Error: while getting user id, first user object `_id` key " + log("API Error: while getting user id, first user object `_id` key " "is not a " "string"); return Failure; diff --git a/src/providers/twitch/PubsubClient.cpp b/src/providers/twitch/PubsubClient.cpp index 7cdd343ce..7f591aebc 100644 --- a/src/providers/twitch/PubsubClient.cpp +++ b/src/providers/twitch/PubsubClient.cpp @@ -109,7 +109,7 @@ void PubSubClient::handlePong() { assert(this->awaitingPong_); - Log("Got pong!"); + log("Got pong!"); this->awaitingPong_ = false; } @@ -144,7 +144,7 @@ void PubSubClient::ping() } if (self->awaitingPong_) { - Log("No pong respnose, disconnect!"); + log("No pong respnose, disconnect!"); // TODO(pajlada): Label this connection as "disconnect me" } }); @@ -166,7 +166,7 @@ bool PubSubClient::send(const char *payload) websocketpp::frame::opcode::text, ec); if (ec) { - Log("Error sending message {}: {}", payload, ec.message()); + log("Error sending message {}: {}", payload, ec.message()); // TODO(pajlada): Check which error code happened and maybe gracefully // handle it @@ -207,26 +207,26 @@ PubSub::PubSub() action.state = ModeChangedAction::State::On; if (!data.HasMember("args")) { - Log("Missing required args member"); + log("Missing required args member"); return; } const auto &args = data["args"]; if (!args.IsArray()) { - Log("args member must be an array"); + log("args member must be an array"); return; } if (args.Size() == 0) { - Log("Missing duration argument in slowmode on"); + log("Missing duration argument in slowmode on"); return; } const auto &durationArg = args[0]; if (!durationArg.IsString()) { - Log("Duration arg must be a string"); + log("Duration arg must be a string"); return; } @@ -314,7 +314,7 @@ PubSub::PubSub() return; } } catch (const std::runtime_error &ex) { - Log("Error parsing moderation action: {}", ex.what()); + log("Error parsing moderation action: {}", ex.what()); } action.modded = false; @@ -339,7 +339,7 @@ PubSub::PubSub() return; } } catch (const std::runtime_error &ex) { - Log("Error parsing moderation action: {}", ex.what()); + log("Error parsing moderation action: {}", ex.what()); } action.modded = true; @@ -380,7 +380,7 @@ PubSub::PubSub() this->signals_.moderation.userBanned.invoke(action); } catch (const std::runtime_error &ex) { - Log("Error parsing moderation action: {}", ex.what()); + log("Error parsing moderation action: {}", ex.what()); } }; @@ -410,7 +410,7 @@ PubSub::PubSub() this->signals_.moderation.userBanned.invoke(action); } catch (const std::runtime_error &ex) { - Log("Error parsing moderation action: {}", ex.what()); + log("Error parsing moderation action: {}", ex.what()); } }; @@ -436,7 +436,7 @@ PubSub::PubSub() this->signals_.moderation.userUnbanned.invoke(action); } catch (const std::runtime_error &ex) { - Log("Error parsing moderation action: {}", ex.what()); + log("Error parsing moderation action: {}", ex.what()); } }; @@ -462,7 +462,7 @@ PubSub::PubSub() this->signals_.moderation.userUnbanned.invoke(action); } catch (const std::runtime_error &ex) { - Log("Error parsing moderation action: {}", ex.what()); + log("Error parsing moderation action: {}", ex.what()); } }; @@ -493,7 +493,7 @@ void PubSub::addClient() auto con = this->websocketClient.get_connection(TWITCH_PUBSUB_URL, ec); if (ec) { - Log("Unable to establish connection: {}", ec.message()); + log("Unable to establish connection: {}", ec.message()); return; } @@ -512,7 +512,7 @@ void PubSub::listenToWhispers(std::shared_ptr account) std::string userID = account->getUserId().toStdString(); - Log("Connection open!"); + log("Connection open!"); websocketpp::lib::error_code ec; std::vector topics({"whispers." + userID}); @@ -520,7 +520,7 @@ void PubSub::listenToWhispers(std::shared_ptr account) this->listen(createListenMessage(topics, account)); if (ec) { - Log("Unable to send message to websocket server: {}", ec.message()); + log("Unable to send message to websocket server: {}", ec.message()); return; } } @@ -544,11 +544,11 @@ void PubSub::listenToChannelModerationActions( std::string topic(fS("chat_moderator_actions.{}.{}", userID, channelID)); if (this->isListeningToTopic(topic)) { - Log("We are already listening to topic {}", topic); + log("We are already listening to topic {}", topic); return; } - Log("Listen to topic {}", topic); + log("Listen to topic {}", topic); this->listenToTopic(topic, account); } @@ -564,18 +564,18 @@ void PubSub::listenToTopic(const std::string &topic, void PubSub::listen(rapidjson::Document &&msg) { if (this->tryListen(msg)) { - Log("Successfully listened!"); + log("Successfully listened!"); return; } - Log("Added to the back of the queue"); + log("Added to the back of the queue"); this->requests.emplace_back( std::make_unique(std::move(msg))); } bool PubSub::tryListen(rapidjson::Document &msg) { - Log("tryListen with {} clients", this->clients.size()); + log("tryListen with {} clients", this->clients.size()); for (const auto &p : this->clients) { const auto &client = p.second; if (client->listen(msg)) { @@ -608,13 +608,13 @@ void PubSub::onMessage(websocketpp::connection_hdl hdl, rapidjson::ParseResult res = msg.Parse(payload.c_str()); if (!res) { - Log("Error parsing message '{}' from PubSub: {}", payload, + log("Error parsing message '{}' from PubSub: {}", payload, rapidjson::GetParseError_En(res.Code())); return; } if (!msg.IsObject()) { - Log("Error parsing message '{}' from PubSub. Root object is not an " + log("Error parsing message '{}' from PubSub. Root object is not an " "object", payload); return; @@ -623,7 +623,7 @@ void PubSub::onMessage(websocketpp::connection_hdl hdl, std::string type; if (!rj::getSafe(msg, "type", type)) { - Log("Missing required string member `type` in message root"); + log("Missing required string member `type` in message root"); return; } @@ -631,14 +631,14 @@ void PubSub::onMessage(websocketpp::connection_hdl hdl, this->handleListenResponse(msg); } else if (type == "MESSAGE") { if (!msg.HasMember("data")) { - Log("Missing required object member `data` in message root"); + log("Missing required object member `data` in message root"); return; } const auto &data = msg["data"]; if (!data.IsObject()) { - Log("Member `data` must be an object"); + log("Member `data` must be an object"); return; } @@ -654,7 +654,7 @@ void PubSub::onMessage(websocketpp::connection_hdl hdl, client.second->handlePong(); } else { - Log("Unknown message type: {}", type); + log("Unknown message type: {}", type); } } @@ -699,7 +699,7 @@ PubSub::WebsocketContextPtr PubSub::onTLSInit(websocketpp::connection_hdl hdl) boost::asio::ssl::context::no_sslv2 | boost::asio::ssl::context::single_dh_use); } catch (const std::exception &e) { - Log("Exception caught in OnTLSInit: {}", e.what()); + log("Exception caught in OnTLSInit: {}", e.what()); } return ctx; @@ -714,12 +714,12 @@ void PubSub::handleListenResponse(const rapidjson::Document &msg) rj::getSafe(msg, "nonce", nonce); if (error.empty()) { - Log("Successfully listened to nonce {}", nonce); + log("Successfully listened to nonce {}", nonce); // Nothing went wrong return; } - Log("PubSub error: {} on nonce {}", error, nonce); + log("PubSub error: {} on nonce {}", error, nonce); return; } } @@ -729,14 +729,14 @@ void PubSub::handleMessageResponse(const rapidjson::Value &outerData) QString topic; if (!rj::getSafe(outerData, "topic", topic)) { - Log("Missing required string member `topic` in outerData"); + log("Missing required string member `topic` in outerData"); return; } std::string payload; if (!rj::getSafe(outerData, "message", payload)) { - Log("Expected string message in outerData"); + log("Expected string message in outerData"); return; } @@ -745,7 +745,7 @@ void PubSub::handleMessageResponse(const rapidjson::Value &outerData) rapidjson::ParseResult res = msg.Parse(payload.c_str()); if (!res) { - Log("Error parsing message '{}' from PubSub: {}", payload, + log("Error parsing message '{}' from PubSub: {}", payload, rapidjson::GetParseError_En(res.Code())); return; } @@ -754,7 +754,7 @@ void PubSub::handleMessageResponse(const rapidjson::Value &outerData) std::string whisperType; if (!rj::getSafe(msg, "type", whisperType)) { - Log("Bad whisper data"); + log("Bad whisper data"); return; } @@ -765,7 +765,7 @@ void PubSub::handleMessageResponse(const rapidjson::Value &outerData) } else if (whisperType == "thread") { // Handle thread? } else { - Log("Invalid whisper type: {}", whisperType); + log("Invalid whisper type: {}", whisperType); assert(false); return; } @@ -777,30 +777,30 @@ void PubSub::handleMessageResponse(const rapidjson::Value &outerData) std::string moderationAction; if (!rj::getSafe(data, "moderation_action", moderationAction)) { - Log("Missing moderation action in data: {}", rj::stringify(data)); + log("Missing moderation action in data: {}", rj::stringify(data)); return; } auto handlerIt = this->moderationActionHandlers.find(moderationAction); if (handlerIt == this->moderationActionHandlers.end()) { - Log("No handler found for moderation action {}", moderationAction); + log("No handler found for moderation action {}", moderationAction); return; } // Invoke handler function handlerIt->second(data, topicParts[2]); } else { - Log("Unknown topic: {}", topic); + log("Unknown topic: {}", topic); return; } } void PubSub::runThread() { - Log("Start pubsub manager thread"); + log("Start pubsub manager thread"); this->websocketClient.run(); - Log("Done with pubsub manager thread"); + log("Done with pubsub manager thread"); } } // namespace chatterino diff --git a/src/providers/twitch/PubsubHelpers.hpp b/src/providers/twitch/PubsubHelpers.hpp index a891edd4f..8b9b3f322 100644 --- a/src/providers/twitch/PubsubHelpers.hpp +++ b/src/providers/twitch/PubsubHelpers.hpp @@ -35,7 +35,7 @@ void runAfter(boost::asio::io_service &ioService, Duration duration, timer->async_wait([timer, cb](const boost::system::error_code &ec) { if (ec) { - Log("Error in runAfter: {}", ec.message()); + log("Error in runAfter: {}", ec.message()); return; } @@ -52,7 +52,7 @@ void runAfter(std::shared_ptr timer, timer->async_wait([timer, cb](const boost::system::error_code &ec) { if (ec) { - Log("Error in runAfter: {}", ec.message()); + log("Error in runAfter: {}", ec.message()); return; } diff --git a/src/providers/twitch/TwitchAccount.cpp b/src/providers/twitch/TwitchAccount.cpp index 0f8b79a44..95a8d37eb 100644 --- a/src/providers/twitch/TwitchAccount.cpp +++ b/src/providers/twitch/TwitchAccount.cpp @@ -143,7 +143,7 @@ void TwitchAccount::loadIgnores() } TwitchUser ignoredUser; if (!rj::getSafe(userIt->value, ignoredUser)) { - Log("Error parsing twitch user JSON {}", + log("Error parsing twitch user JSON {}", rj::stringify(userIt->value)); continue; } @@ -368,13 +368,13 @@ std::set TwitchAccount::getIgnores() const void TwitchAccount::loadEmotes() { - Log("Loading Twitch emotes for user {}", this->getUserName()); + log("Loading Twitch emotes for user {}", this->getUserName()); const auto &clientID = this->getOAuthClient(); const auto &oauthToken = this->getOAuthToken(); if (clientID.isEmpty() || oauthToken.isEmpty()) { - Log("Missing Client ID or OAuth token"); + log("Missing Client ID or OAuth token"); return; } @@ -386,7 +386,7 @@ void TwitchAccount::loadEmotes() req.makeAuthorizedV5(this->getOAuthClient(), this->getOAuthToken()); req.onError([=](int errorCode) { - Log("[TwitchAccount::loadEmotes] Error {}", errorCode); + log("[TwitchAccount::loadEmotes] Error {}", errorCode); if (errorCode == 203) { // onFinished(FollowResult_NotFollowing); } else { @@ -420,7 +420,7 @@ void TwitchAccount::parseEmotes(const rapidjson::Document &root) auto emoticonSets = root.FindMember("emoticon_sets"); if (emoticonSets == root.MemberEnd() || !emoticonSets->value.IsObject()) { - Log("No emoticon_sets in load emotes response"); + log("No emoticon_sets in load emotes response"); return; } @@ -434,19 +434,19 @@ void TwitchAccount::parseEmotes(const rapidjson::Document &root) for (const rapidjson::Value &emoteJSON : emoteSetJSON.value.GetArray()) { if (!emoteJSON.IsObject()) { - Log("Emote value was invalid"); + log("Emote value was invalid"); return; } uint64_t idNumber; if (!rj::getSafe(emoteJSON, "id", idNumber)) { - Log("No ID key found in Emote value"); + log("No ID key found in Emote value"); return; } QString _code; if (!rj::getSafe(emoteJSON, "code", _code)) { - Log("No code key found in Emote value"); + log("No code key found in Emote value"); return; } @@ -468,7 +468,7 @@ void TwitchAccount::parseEmotes(const rapidjson::Document &root) void TwitchAccount::loadEmoteSetData(std::shared_ptr emoteSet) { if (!emoteSet) { - Log("null emote set sent"); + log("null emote set sent"); return; } @@ -486,7 +486,7 @@ void TwitchAccount::loadEmoteSetData(std::shared_ptr emoteSet) req.setUseQuickLoadCache(true); req.onError([](int errorCode) -> bool { - Log("Error code {} while loading emote set data", errorCode); + log("Error code {} while loading emote set data", errorCode); return true; }); @@ -507,16 +507,15 @@ void TwitchAccount::loadEmoteSetData(std::shared_ptr emoteSet) return Failure; } - Log("Loaded twitch emote set data for {}!", emoteSet->key); + log("Loaded twitch emote set data for {}!", emoteSet->key); - if (type == "sub") { - emoteSet->text = - QString("Twitch Subscriber Emote (%1)").arg(channelName); - } else { - emoteSet->text = - QString("Twitch Account Emote (%1)").arg(channelName); - } + auto name = channelName; + name.detach(); + name[0] = name[0].toUpper(); + emoteSet->text = name; + + emoteSet->type = type; emoteSet->channelName = channelName; return Success; diff --git a/src/providers/twitch/TwitchAccount.hpp b/src/providers/twitch/TwitchAccount.hpp index 1a180f5e2..21dfbac63 100644 --- a/src/providers/twitch/TwitchAccount.hpp +++ b/src/providers/twitch/TwitchAccount.hpp @@ -44,6 +44,7 @@ public: QString key; QString channelName; QString text; + QString type; std::vector emotes; }; diff --git a/src/providers/twitch/TwitchAccountManager.cpp b/src/providers/twitch/TwitchAccountManager.cpp index 7d4f932eb..18210c2fd 100644 --- a/src/providers/twitch/TwitchAccountManager.cpp +++ b/src/providers/twitch/TwitchAccountManager.cpp @@ -93,20 +93,20 @@ void TwitchAccountManager::reloadUsers() switch (this->addUser(userData)) { case AddUserResponse::UserAlreadyExists: { - Log("User {} already exists", userData.username); + log("User {} already exists", userData.username); // Do nothing } break; case AddUserResponse::UserValuesUpdated: { - Log("User {} already exists, and values updated!", + log("User {} already exists, and values updated!", userData.username); if (userData.username == this->getCurrent()->getUserName()) { - Log("It was the current user, so we need to reconnect " + log("It was the current user, so we need to reconnect " "stuff!"); this->currentUserChanged.invoke(); } } break; case AddUserResponse::UserAdded: { - Log("Added user {}", userData.username); + log("Added user {}", userData.username); listUpdated = true; } break; } @@ -125,12 +125,12 @@ void TwitchAccountManager::load() QString newUsername(QString::fromStdString(newValue)); auto user = this->findUserByUsername(newUsername); if (user) { - Log("[AccountManager:currentUsernameChanged] User successfully " + log("[AccountManager:currentUsernameChanged] User successfully " "updated to {}", newUsername); this->currentUser_ = user; } else { - Log("[AccountManager:currentUsernameChanged] User successfully " + log("[AccountManager:currentUsernameChanged] User successfully " "updated to anonymous"); this->currentUser_ = this->anonymousUser_; } diff --git a/src/providers/twitch/TwitchApi.cpp b/src/providers/twitch/TwitchApi.cpp index 6b1e537c3..dc0329b69 100644 --- a/src/providers/twitch/TwitchApi.cpp +++ b/src/providers/twitch/TwitchApi.cpp @@ -20,25 +20,25 @@ void TwitchApi::findUserId(const QString user, request.onSuccess([successCallback](auto result) mutable -> Outcome { auto root = result.parseJson(); if (!root.value("users").isArray()) { - Log("API Error while getting user id, users is not an array"); + log("API Error while getting user id, users is not an array"); successCallback(""); return Failure; } auto users = root.value("users").toArray(); if (users.size() != 1) { - Log("API Error while getting user id, users array size is not 1"); + log("API Error while getting user id, users array size is not 1"); successCallback(""); return Failure; } if (!users[0].isObject()) { - Log("API Error while getting user id, first user is not an object"); + log("API Error while getting user id, first user is not an object"); successCallback(""); return Failure; } auto firstUser = users[0].toObject(); auto id = firstUser.value("_id"); if (!id.isString()) { - Log("API Error: while getting user id, first user object `_id` key " + log("API Error: while getting user id, first user object `_id` key " "is not a " "string"); successCallback(""); diff --git a/src/providers/twitch/TwitchChannel.cpp b/src/providers/twitch/TwitchChannel.cpp index 04b0f2666..4d9445c75 100644 --- a/src/providers/twitch/TwitchChannel.cpp +++ b/src/providers/twitch/TwitchChannel.cpp @@ -56,7 +56,7 @@ TwitchChannel::TwitchChannel(const QString &name) , popoutPlayerUrl_("https://player.twitch.tv/?channel=" + name) , mod_(false) { - Log("[TwitchChannel:{}] Opened", name); + log("[TwitchChannel:{}] Opened", name); // this->refreshChannelEmotes(); // this->refreshViewerList(); @@ -116,7 +116,7 @@ void TwitchChannel::refreshChannelEmotes() if (auto shared = weak.lock()) // *this->bttvEmotes_.access() = emoteMap; }); - getApp()->emotes->ffz.loadChannelEmotes( + getApp()->emotes->ffz.loadChannel( this->getName(), [this, weak = weakOf(this)](auto &&emoteMap) { if (auto shared = weak.lock()) *this->ffzEmotes_.access() = emoteMap; @@ -136,7 +136,7 @@ void TwitchChannel::sendMessage(const QString &message) return; } - Log("[TwitchChannel:{}] Send message: {}", this->getName(), message); + log("[TwitchChannel:{}] Send message: {}", this->getName(), message); // Do last message processing QString parsedMessage = app->emotes->emojis.replaceShortCodes(message); @@ -350,13 +350,13 @@ void TwitchChannel::refreshLiveStatus() auto roomID = this->getRoomId(); if (roomID.isEmpty()) { - Log("[TwitchChannel:{}] Refreshing live status (Missing ID)", + log("[TwitchChannel:{}] Refreshing live status (Missing ID)", this->getName()); this->setLive(false); return; } - Log("[TwitchChannel:{}] Refreshing live status", this->getName()); + log("[TwitchChannel:{}] Refreshing live status", this->getName()); QString url("https://api.twitch.tv/kraken/streams/" + roomID); @@ -381,12 +381,12 @@ void TwitchChannel::refreshLiveStatus() Outcome TwitchChannel::parseLiveStatus(const rapidjson::Document &document) { if (!document.IsObject()) { - Log("[TwitchChannel:refreshLiveStatus] root is not an object"); + log("[TwitchChannel:refreshLiveStatus] root is not an object"); return Failure; } if (!document.HasMember("stream")) { - Log("[TwitchChannel:refreshLiveStatus] Missing stream in root"); + log("[TwitchChannel:refreshLiveStatus] Missing stream in root"); return Failure; } @@ -400,7 +400,7 @@ Outcome TwitchChannel::parseLiveStatus(const rapidjson::Document &document) if (!stream.HasMember("viewers") || !stream.HasMember("game") || !stream.HasMember("channel") || !stream.HasMember("created_at")) { - Log("[TwitchChannel:refreshLiveStatus] Missing members in stream"); + log("[TwitchChannel:refreshLiveStatus] Missing members in stream"); this->setLive(false); return Failure; } @@ -408,7 +408,7 @@ Outcome TwitchChannel::parseLiveStatus(const rapidjson::Document &document) const rapidjson::Value &streamChannel = stream["channel"]; if (!streamChannel.IsObject() || !streamChannel.HasMember("status")) { - Log("[TwitchChannel:refreshLiveStatus] Missing member \"status\" in " + log("[TwitchChannel:refreshLiveStatus] Missing member \"status\" in " "channel"); return Failure; } diff --git a/src/providers/twitch/TwitchChannel.hpp b/src/providers/twitch/TwitchChannel.hpp index 5befb6700..e41120cda 100644 --- a/src/providers/twitch/TwitchChannel.hpp +++ b/src/providers/twitch/TwitchChannel.hpp @@ -4,7 +4,7 @@ #include "common/Channel.hpp" #include "common/Common.hpp" -#include "common/MutexValue.hpp" +#include "common/Atomic.hpp" #include "common/UniqueAccess.hpp" #include "messages/Emote.hpp" #include "singletons/Emotes.hpp" diff --git a/src/providers/twitch/TwitchHelpers.cpp b/src/providers/twitch/TwitchHelpers.cpp index f236b10cb..9999e125c 100644 --- a/src/providers/twitch/TwitchHelpers.cpp +++ b/src/providers/twitch/TwitchHelpers.cpp @@ -6,7 +6,7 @@ namespace chatterino { bool trimChannelName(const QString &channelName, QString &outChannelName) { if (channelName.length() < 3) { - Log("channel name length below 3"); + log("channel name length below 3"); return false; } diff --git a/src/providers/twitch/TwitchMessageBuilder.cpp b/src/providers/twitch/TwitchMessageBuilder.cpp index eeb4ed4b0..fef0e4a23 100644 --- a/src/providers/twitch/TwitchMessageBuilder.cpp +++ b/src/providers/twitch/TwitchMessageBuilder.cpp @@ -55,7 +55,7 @@ bool TwitchMessageBuilder::isIgnored() const // TODO(pajlada): Do we need to check if the phrase is valid first? for (const auto &phrase : app->ignores->phrases.getVector()) { if (phrase.isMatch(this->originalMessage_)) { - Log("Blocking message because it contains ignored phrase {}", + log("Blocking message because it contains ignored phrase {}", phrase.getPattern()); return true; } @@ -68,7 +68,7 @@ bool TwitchMessageBuilder::isIgnored() const for (const auto &user : app->accounts->twitch.getCurrent()->getIgnores()) { if (sourceUserID == user.id) { - Log("Blocking message because it's from blocked user {}", + log("Blocking message because it's from blocked user {}", user.name); return true; } @@ -533,7 +533,7 @@ void TwitchMessageBuilder::parseHighlights(bool isPastMsg) if (!app->highlights->blacklistContains(this->ircMessage->nick())) { for (const HighlightPhrase &highlight : activeHighlights) { if (highlight.isMatch(this->originalMessage_)) { - Log("Highlight because {} matches {}", this->originalMessage_, + log("Highlight because {} matches {}", this->originalMessage_, highlight.getPattern()); doHighlight = true; @@ -555,7 +555,7 @@ void TwitchMessageBuilder::parseHighlights(bool isPastMsg) } for (const HighlightPhrase &userHighlight : userHighlights) { if (userHighlight.isMatch(this->ircMessage->nick())) { - Log("Highlight because user {} sent a message", + log("Highlight because user {} sent a message", this->ircMessage->nick()); doHighlight = true; @@ -638,12 +638,12 @@ Outcome TwitchMessageBuilder::tryAppendEmote(const EmoteName &name) auto flags = MessageElementFlags(); auto emote = boost::optional{}; - if ((emote = getApp()->emotes->bttv.getGlobalEmote(name))) { + if ((emote = getApp()->emotes->bttv.global(name))) { flags = MessageElementFlag::BttvEmote; } else if (twitchChannel && (emote = this->twitchChannel->getBttvEmote(name))) { flags = MessageElementFlag::BttvEmote; - } else if ((emote = getApp()->emotes->ffz.getGlobalEmote(name))) { + } else if ((emote = getApp()->emotes->ffz.global(name))) { flags = MessageElementFlag::FfzEmote; } else if (twitchChannel && (emote = this->twitchChannel->getFfzEmote(name))) { diff --git a/src/providers/twitch/TwitchMessageBuilder.hpp b/src/providers/twitch/TwitchMessageBuilder.hpp index c82364a67..385fed932 100644 --- a/src/providers/twitch/TwitchMessageBuilder.hpp +++ b/src/providers/twitch/TwitchMessageBuilder.hpp @@ -1,7 +1,6 @@ #pragma once #include "messages/MessageBuilder.hpp" -#include "messages/MessageParseArgs.hpp" #include "singletons/Emotes.hpp" #include diff --git a/src/providers/twitch/TwitchServer.hpp b/src/providers/twitch/TwitchServer.hpp index edc06ef6a..7e204173f 100644 --- a/src/providers/twitch/TwitchServer.hpp +++ b/src/providers/twitch/TwitchServer.hpp @@ -1,6 +1,6 @@ #pragma once -#include "common/MutexValue.hpp" +#include "common/Atomic.hpp" #include "common/Singleton.hpp" #include "providers/irc/AbstractIrcServer.hpp" #include "providers/twitch/TwitchAccount.hpp" @@ -29,7 +29,7 @@ public: std::shared_ptr getChannelOrEmptyByID(const QString &channelID); - MutexValue lastUserThatWhisperedMe; + Atomic lastUserThatWhisperedMe; const ChannelPtr whispersChannel; const ChannelPtr mentionsChannel; diff --git a/src/singletons/Emotes.cpp b/src/singletons/Emotes.cpp index 0be870a5e..cfc23f6d4 100644 --- a/src/singletons/Emotes.cpp +++ b/src/singletons/Emotes.cpp @@ -15,8 +15,8 @@ void Emotes::initialize(Settings &settings, Paths &paths) [] { getApp()->accounts->twitch.getCurrent()->loadEmotes(); }); this->emojis.load(); - this->bttv.loadGlobalEmotes(); - this->ffz.loadGlobalEmotes(); + this->bttv.loadGlobal(); + this->ffz.loadGlobal(); this->gifTimer.initialize(); } diff --git a/src/singletons/Settings.cpp b/src/singletons/Settings.cpp index b380a0119..ea5318ab3 100644 --- a/src/singletons/Settings.cpp +++ b/src/singletons/Settings.cpp @@ -50,7 +50,7 @@ void Settings::saveSnapshot() this->snapshot_.reset(d); - Log("hehe: {}", pajlada::Settings::SettingManager::stringify(*d)); + log("hehe: {}", pajlada::Settings::SettingManager::stringify(*d)); } void Settings::restoreSnapshot() @@ -64,14 +64,14 @@ void Settings::restoreSnapshot() for (const auto &weakSetting : _settings) { auto setting = weakSetting.lock(); if (!setting) { - Log("Error stage 1 of loading"); + log("Error stage 1 of loading"); continue; } const char *path = setting->getPath().c_str(); if (!snapshotObject.HasMember(path)) { - Log("Error stage 2 of loading"); + log("Error stage 2 of loading"); continue; } diff --git a/src/singletons/WindowManager.cpp b/src/singletons/WindowManager.cpp index 23b8c4e1b..8ff34c7bf 100644 --- a/src/singletons/WindowManager.cpp +++ b/src/singletons/WindowManager.cpp @@ -211,7 +211,7 @@ Window *WindowManager::windowAt(int index) if (index < 0 || (size_t)index >= this->windows_.size()) { return nullptr; } - Log("getting window at bad index {}", index); + log("getting window at bad index {}", index); return this->windows_.at(index); } diff --git a/src/singletons/helper/LoggingChannel.cpp b/src/singletons/helper/LoggingChannel.cpp index 97a0b8478..d70344448 100644 --- a/src/singletons/helper/LoggingChannel.cpp +++ b/src/singletons/helper/LoggingChannel.cpp @@ -65,13 +65,13 @@ void LoggingChannel::openLogFile() this->baseDirectory + QDir::separator() + this->subDirectory; if (!QDir().mkpath(directory)) { - Log("Unable to create logging path"); + log("Unable to create logging path"); return; } // Open file handle to log file of current date QString fileName = directory + QDir::separator() + baseFileName; - Log("Logging to {}", fileName); + log("Logging to {}", fileName); this->fileHandle.setFileName(fileName); this->fileHandle.open(QIODevice::Append); diff --git a/src/util/Helpers.hpp b/src/util/Helpers.hpp index b708728b1..1552ae404 100644 --- a/src/util/Helpers.hpp +++ b/src/util/Helpers.hpp @@ -6,7 +6,7 @@ namespace chatterino { template -auto fS(Args &&... args) -> decltype(fmt::format(std::forward(args)...)) +auto fS(Args &&... args) { return fmt::format(std::forward(args)...); } diff --git a/src/widgets/dialogs/EmotePopup.cpp b/src/widgets/dialogs/EmotePopup.cpp index 3f8c6ac1d..b5dbb965b 100644 --- a/src/widgets/dialogs/EmotePopup.cpp +++ b/src/widgets/dialogs/EmotePopup.cpp @@ -2,6 +2,7 @@ #include "Application.hpp" #include "controllers/accounts/AccountController.hpp" +#include "debug/Benchmark.hpp" #include "messages/MessageBuilder.hpp" #include "providers/twitch/TwitchChannel.hpp" #include "widgets/Notebook.hpp" @@ -11,36 +12,88 @@ #include namespace chatterino { +namespace { +auto makeTitleMessage(const QString &title) +{ + MessageBuilder builder; + builder.emplace(title, MessageElementFlag::Text); + builder->flags.set(MessageFlag::Centered); + return builder.release(); +} +auto makeEmoteMessage(const EmoteMap &map) +{ + MessageBuilder builder; + builder->flags.set(MessageFlag::Centered); + builder->flags.set(MessageFlag::DisableCompactEmotes); + + for (const auto &emote : map) { + builder + .emplace(emote.second, MessageElementFlag::AlwaysShow) + ->setLink(Link(Link::InsertText, emote.first.string)); + } + + return builder.release(); +} +void addEmoteSets(std::vector> sets, + Channel &globalChannel, Channel &subChannel) +{ + for (const auto &set : sets) { + auto &channel = set->key == "0" ? globalChannel : subChannel; + + // TITLE + auto text = + set->key == "0" || set->text.isEmpty() ? "Twitch" : set->text; + channel.addMessage(makeTitleMessage(text)); + + // EMOTES + MessageBuilder builder; + builder->flags.set(MessageFlag::Centered); + builder->flags.set(MessageFlag::DisableCompactEmotes); + + for (const auto &emote : set->emotes) { + builder + .emplace( + getApp()->emotes->twitch.getOrCreateEmote(emote.id, + emote.name), + MessageElementFlag::AlwaysShow) + ->setLink(Link(Link::InsertText, emote.name.string)); + } + + channel.addMessage(builder.release()); + } +} +} // namespace EmotePopup::EmotePopup() : BaseWindow(nullptr, BaseWindow::EnableCustomFrame) { - this->viewEmotes_ = new ChannelView(); - this->viewEmojis_ = new ChannelView(); - - this->viewEmotes_->setOverrideFlags(MessageElementFlags{ - MessageElementFlag::Default, MessageElementFlag::AlwaysShow, - MessageElementFlag::EmoteImages}); - this->viewEmojis_->setOverrideFlags(MessageElementFlags{ - MessageElementFlag::Default, MessageElementFlag::AlwaysShow, - MessageElementFlag::EmoteImages}); - - this->viewEmotes_->setEnableScrollingToBottom(false); - this->viewEmojis_->setEnableScrollingToBottom(false); - - auto *layout = new QVBoxLayout(this); + auto layout = new QVBoxLayout(this); this->getLayoutContainer()->setLayout(layout); - Notebook *notebook = new Notebook(this); + auto notebook = new Notebook(this); layout->addWidget(notebook); layout->setMargin(0); - notebook->addPage(this->viewEmotes_, "Emotes"); - notebook->addPage(this->viewEmojis_, "Emojis"); + auto makeView = [&](QString tabTitle) { + auto view = new ChannelView(); + + view->setOverrideFlags(MessageElementFlags{ + MessageElementFlag::Default, MessageElementFlag::AlwaysShow, + MessageElementFlag::EmoteImages}); + view->setEnableScrollingToBottom(false); + notebook->addPage(view, tabTitle); + + return view; + }; + + this->subEmotesView_ = makeView("Subs"); + this->channelEmotesView_ = makeView("Channel"); + this->globalEmotesView_ = makeView("Global"); + this->viewEmojis_ = makeView("Emojis"); this->loadEmojis(); - this->viewEmotes_->linkClicked.connect( + this->globalEmotesView_->linkClicked.connect( [this](const Link &link) { this->linkClicked.invoke(link); }); this->viewEmojis_->linkClicked.connect( [this](const Link &link) { this->linkClicked.invoke(link); }); @@ -48,93 +101,41 @@ EmotePopup::EmotePopup() void EmotePopup::loadChannel(ChannelPtr _channel) { + BenchmarkGuard guard("loadChannel"); + this->setWindowTitle("Emotes from " + _channel->getName()); - TwitchChannel *channel = dynamic_cast(_channel.get()); + auto twitchChannel = dynamic_cast(_channel.get()); + if (twitchChannel == nullptr) return; - if (channel == nullptr) { - return; - } - - ChannelPtr emoteChannel(new Channel("", Channel::Type::None)); - - auto addEmotes = [&](const EmoteMap &map, const QString &title, - const QString &emoteDesc) { - // TITLE - MessageBuilder builder1; - - builder1.emplace(title, MessageElementFlag::Text); - - builder1->flags.set(MessageFlag::Centered); - emoteChannel->addMessage(builder1.release()); - - // EMOTES - MessageBuilder builder2; - builder2->flags.set(MessageFlag::Centered); - builder2->flags.set(MessageFlag::DisableCompactEmotes); - - for (auto emote : map) { - builder2 - .emplace(emote.second, - MessageElementFlag::AlwaysShow) - ->setLink(Link(Link::InsertText, emote.first.string)); - } - - emoteChannel->addMessage(builder2.release()); + auto addEmotes = [&](Channel &channel, const EmoteMap &map, + const QString &title) { + channel.addMessage(makeTitleMessage(title)); + channel.addMessage(makeEmoteMessage(map)); }; - auto app = getApp(); + auto subChannel = std::make_shared("", Channel::Type::None); + auto globalChannel = std::make_shared("", Channel::Type::None); + auto channelChannel = std::make_shared("", Channel::Type::None); - // fourtf: the entire emote manager needs to be refactored so there's no - // point in trying to fix this pile of garbage - for (const auto &set : - app->accounts->twitch.getCurrent()->accessEmotes()->emoteSets) { - // TITLE - MessageBuilder builder1; + // twitch + addEmoteSets( + getApp()->accounts->twitch.getCurrent()->accessEmotes()->emoteSets, + *globalChannel, *subChannel); - QString setText; - if (set->text.isEmpty()) { - if (set->channelName.isEmpty()) { - setText = "Twitch Account Emotes"; - } else { - setText = "Twitch Account Emotes (" + set->channelName + ")"; - } - } else { - setText = set->text; - } + // global + addEmotes(*globalChannel, *getApp()->emotes->bttv.global(), "BetterTTV"); + addEmotes(*globalChannel, *getApp()->emotes->ffz.global(), "FrankerFaceZ"); - builder1.emplace(setText, MessageElementFlag::Text); + // channel + // addEmotes(*channel->accessBttvEmotes(), "BetterTTV Channel Emotes", + // "BetterTTV Channel Emote"); + // addEmotes(*channel->accessFfzEmotes(), "FrankerFaceZ Channel Emotes", + // "FrankerFaceZ Channel Emote"); - builder1->flags.set(MessageFlag::Centered); - emoteChannel->addMessage(builder1.release()); - - // EMOTES - MessageBuilder builder2; - builder2->flags.set(MessageFlag::Centered); - builder2->flags.set(MessageFlag::DisableCompactEmotes); - - for (const auto &emote : set->emotes) { - builder2 - .emplace( - app->emotes->twitch.getOrCreateEmote(emote.id, emote.name), - MessageElementFlag::AlwaysShow) - ->setLink(Link(Link::InsertText, emote.name.string)); - } - - emoteChannel->addMessage(builder2.release()); - } - - addEmotes(*app->emotes->bttv.accessGlobalEmotes(), - "BetterTTV Global Emotes", "BetterTTV Global Emote"); - addEmotes(*channel->accessBttvEmotes(), "BetterTTV Channel Emotes", - "BetterTTV Channel Emote"); - // addEmotes(*app->emotes->ffz.accessGlobalEmotes(), "FrankerFaceZ Global - // Emotes", - // "FrankerFaceZ Global Emote"); - addEmotes(*channel->accessFfzEmotes(), "FrankerFaceZ Channel Emotes", - "FrankerFaceZ Channel Emote"); - - this->viewEmotes_->setChannel(emoteChannel); + this->globalEmotesView_->setChannel(globalChannel); + this->subEmotesView_->setChannel(subChannel); + this->channelEmotesView_->setChannel(channelChannel); } void EmotePopup::loadEmojis() @@ -143,13 +144,6 @@ void EmotePopup::loadEmojis() ChannelPtr emojiChannel(new Channel("", Channel::Type::None)); - // title - MessageBuilder builder1; - - builder1.emplace("emojis", MessageElementFlag::Text); - builder1->flags.set(MessageFlag::Centered); - emojiChannel->addMessage(builder1.release()); - // emojis MessageBuilder builder; builder->flags.set(MessageFlag::Centered); diff --git a/src/widgets/dialogs/EmotePopup.hpp b/src/widgets/dialogs/EmotePopup.hpp index ad89a37d0..98331efa7 100644 --- a/src/widgets/dialogs/EmotePopup.hpp +++ b/src/widgets/dialogs/EmotePopup.hpp @@ -19,8 +19,10 @@ public: pajlada::Signals::Signal linkClicked; private: - ChannelView *viewEmotes_; - ChannelView *viewEmojis_; + ChannelView *globalEmotesView_{}; + ChannelView *channelEmotesView_{}; + ChannelView *subEmotesView_{}; + ChannelView *viewEmojis_{}; }; } // namespace chatterino diff --git a/src/widgets/dialogs/QualityPopup.cpp b/src/widgets/dialogs/QualityPopup.cpp index c4f9c4ceb..94bbf5594 100644 --- a/src/widgets/dialogs/QualityPopup.cpp +++ b/src/widgets/dialogs/QualityPopup.cpp @@ -47,7 +47,7 @@ void QualityPopup::okButtonClicked() try { openStreamlink(channelURL, this->ui_.selector.currentText()); } catch (const Exception &ex) { - Log("Exception caught trying to open streamlink: {}", ex.what()); + log("Exception caught trying to open streamlink: {}", ex.what()); } this->close(); diff --git a/src/widgets/helper/ChannelView.cpp b/src/widgets/helper/ChannelView.cpp index e8f90d0fc..3803f2a21 100644 --- a/src/widgets/helper/ChannelView.cpp +++ b/src/widgets/helper/ChannelView.cpp @@ -492,7 +492,7 @@ void ChannelView::setChannel(ChannelPtr newChannel) MessageLayoutPtr newItem(new MessageLayout(replacement)); auto snapshot = this->messages.getSnapshot(); if (index >= snapshot.getLength()) { - Log("Tried to replace out of bounds message. Index: {}. " + log("Tried to replace out of bounds message. Index: {}. " "Length: {}", index, snapshot.getLength()); return; @@ -1169,19 +1169,18 @@ void ChannelView::handleLinkClick(QMouseEvent *event, const Link &link, userPopup->show(); qDebug() << "Clicked " << user << "s message"; - break; - } + + } break; case Link::Url: { QDesktopServices::openUrl(QUrl(link.value)); - break; - } + } break; case Link::UserAction: { QString value = link.value; value.replace("{user}", layout->getMessage()->loginName); this->channel_->sendMessage(value); - } + } break; default:; } diff --git a/src/widgets/settingspages/AboutPage.cpp b/src/widgets/settingspages/AboutPage.cpp index 758467391..1fa5dc40c 100644 --- a/src/widgets/settingspages/AboutPage.cpp +++ b/src/widgets/settingspages/AboutPage.cpp @@ -137,7 +137,7 @@ AboutPage::AboutPage() QStringList contributorParts = line.split("|"); if (contributorParts.size() != 4) { - Log("Missing parts in line '{}'", line); + log("Missing parts in line '{}'", line); continue; } diff --git a/src/widgets/splits/Split.cpp b/src/widgets/splits/Split.cpp index f1f2a463f..38b390697 100644 --- a/src/widgets/splits/Split.cpp +++ b/src/widgets/splits/Split.cpp @@ -429,7 +429,7 @@ void Split::openInStreamlink() try { openStreamlinkForChannel(this->getChannel()->getName()); } catch (const Exception &ex) { - Log("Error in doOpenStreamlink: {}", ex.what()); + log("Error in doOpenStreamlink: {}", ex.what()); } }