diff --git a/src/common/NetworkPrivate.cpp b/src/common/NetworkPrivate.cpp index 9709ba98..764f12d1 100644 --- a/src/common/NetworkPrivate.cpp +++ b/src/common/NetworkPrivate.cpp @@ -16,12 +16,17 @@ namespace chatterino { NetworkData::NetworkData() + : timer_(new QTimer()) { + timer_->setSingleShot(true); + DebugCount::increase("NetworkData"); } NetworkData::~NetworkData() { + this->timer_->deleteLater(); + DebugCount::decrease("NetworkData"); } @@ -75,8 +80,8 @@ void loadUncached(const std::shared_ptr &data) if (data->hasTimeout_) { - data->timer_.setSingleShot(true); - data->timer_.start(); + data->timer_->setSingleShot(true); + data->timer_->start(); } auto onUrlRequested = [data, worker]() mutable { @@ -106,9 +111,9 @@ void loadUncached(const std::shared_ptr &data) return; } - if (data->timer_.isActive()) + if (data->timer_->isActive()) { - QObject::connect(&data->timer_, &QTimer::timeout, worker, + QObject::connect(data->timer_, &QTimer::timeout, worker, [reply, data]() { log("Aborted!"); reply->abort(); @@ -228,7 +233,7 @@ void loadCached(const std::shared_ptr &data) }); } } - } // namespace chatterino + } } void load(const std::shared_ptr &data) diff --git a/src/common/NetworkPrivate.hpp b/src/common/NetworkPrivate.hpp index a9c31516..e951108a 100644 --- a/src/common/NetworkPrivate.hpp +++ b/src/common/NetworkPrivate.hpp @@ -51,7 +51,7 @@ struct NetworkData { // to enable the timer, the "setTimeout" function needs to be called before // execute is called bool hasTimeout_{}; - QTimer timer_; + QTimer *timer_; QString getHash(); diff --git a/src/common/NetworkRequest.cpp b/src/common/NetworkRequest.cpp index 90163525..d9ba3c3e 100644 --- a/src/common/NetworkRequest.cpp +++ b/src/common/NetworkRequest.cpp @@ -50,11 +50,14 @@ NetworkRequest NetworkRequest::type(NetworkRequestType newRequestType) && NetworkRequest NetworkRequest::caller(const QObject *caller) && { - // Caller must be in gui thread - assert(caller->thread() == qApp->thread()); + if (caller) + { + // Caller must be in gui thread + assert(caller->thread() == qApp->thread()); - this->data->caller_ = const_cast(caller); - this->data->hasCaller_ = true; + this->data->caller_ = const_cast(caller); + this->data->hasCaller_ = true; + } return std::move(*this); } @@ -100,7 +103,7 @@ NetworkRequest NetworkRequest::header(const char *headerName, NetworkRequest NetworkRequest::timeout(int ms) && { this->data->hasTimeout_ = true; - this->data->timer_.setInterval(ms); + this->data->timer_->setInterval(ms); return std::move(*this); } diff --git a/src/controllers/notifications/NotificationController.cpp b/src/controllers/notifications/NotificationController.cpp index f86bf3db..40643aa8 100644 --- a/src/controllers/notifications/NotificationController.cpp +++ b/src/controllers/notifications/NotificationController.cpp @@ -156,7 +156,6 @@ void NotificationController::getFakeTwitchChannelLiveStatus( QString url("https://api.twitch.tv/kraken/streams/" + roomID); NetworkRequest::twitchRequest(url) - .caller(QThread::currentThread()) .onSuccess([this, channelName](auto result) -> Outcome { rapidjson::Document document = result.parseRapidJson(); if (!document.IsObject()) diff --git a/src/messages/MessageBuilder.cpp b/src/messages/MessageBuilder.cpp index 96a2d25c..c38bf024 100644 --- a/src/messages/MessageBuilder.cpp +++ b/src/messages/MessageBuilder.cpp @@ -387,26 +387,27 @@ void MessageBuilder::addLink(const QString &origLink, textColor) ->setLink(linkElement); - LinkResolver::getLinkInfo(matchedLink, [weakMessage = this->weakOf(), - linkMELowercase, linkMEOriginal, - matchedLink](QString tooltipText, - Link originalLink) { - auto shared = weakMessage.lock(); - if (!shared) - { - return; - } - if (!tooltipText.isEmpty()) - { - linkMELowercase->setTooltip(tooltipText); - linkMEOriginal->setTooltip(tooltipText); - } - if (originalLink.value != matchedLink && !originalLink.value.isEmpty()) - { - linkMELowercase->setLink(originalLink)->updateLink(); - linkMEOriginal->setLink(originalLink)->updateLink(); - } - }); + LinkResolver::getLinkInfo( + matchedLink, nullptr, + [weakMessage = this->weakOf(), linkMELowercase, linkMEOriginal, + matchedLink](QString tooltipText, Link originalLink) { + auto shared = weakMessage.lock(); + if (!shared) + { + return; + } + if (!tooltipText.isEmpty()) + { + linkMELowercase->setTooltip(tooltipText); + linkMEOriginal->setTooltip(tooltipText); + } + if (originalLink.value != matchedLink && + !originalLink.value.isEmpty()) + { + linkMELowercase->setLink(originalLink)->updateLink(); + linkMEOriginal->setLink(originalLink)->updateLink(); + } + }); } } // namespace chatterino diff --git a/src/providers/LinkResolver.cpp b/src/providers/LinkResolver.cpp index 0de15157..ee4cee69 100644 --- a/src/providers/LinkResolver.cpp +++ b/src/providers/LinkResolver.cpp @@ -11,7 +11,8 @@ namespace chatterino { void LinkResolver::getLinkInfo( - const QString url, std::function successCallback) + const QString url, QObject *caller, + std::function successCallback) { if (!getSettings()->linkInfoTooltip) { @@ -22,7 +23,7 @@ void LinkResolver::getLinkInfo( // QTimer::singleShot(3000, [=]() { NetworkRequest(Env::get().linkResolverUrl.arg(QString::fromUtf8( QUrl::toPercentEncoding(url, "", "/:")))) - .caller(QThread::currentThread()) + .caller(caller) .timeout(30000) .onSuccess([successCallback, url](auto result) mutable -> Outcome { auto root = result.parseJson(); diff --git a/src/providers/LinkResolver.hpp b/src/providers/LinkResolver.hpp index 9905bfed..d4e9804f 100644 --- a/src/providers/LinkResolver.hpp +++ b/src/providers/LinkResolver.hpp @@ -10,10 +10,8 @@ namespace chatterino { class LinkResolver { public: - static void getLinkInfo(const QString url, + static void getLinkInfo(const QString url, QObject *caller, std::function callback); - -private: }; } // namespace chatterino diff --git a/src/providers/bttv/BttvEmotes.cpp b/src/providers/bttv/BttvEmotes.cpp index 4b2602e4..ef3ebfb0 100644 --- a/src/providers/bttv/BttvEmotes.cpp +++ b/src/providers/bttv/BttvEmotes.cpp @@ -113,7 +113,6 @@ boost::optional BttvEmotes::emote(const EmoteName &name) const void BttvEmotes::loadEmotes() { NetworkRequest(QString(globalEmoteApiUrl)) - .caller(QThread::currentThread()) .timeout(30000) .onSuccess([this](auto result) -> Outcome { auto emotes = this->global_.get(); @@ -130,7 +129,6 @@ void BttvEmotes::loadChannel(const QString &channelName, std::function callback) { NetworkRequest(QString(bttvChannelEmoteApiUrl) + channelName) - .caller(QThread::currentThread()) .timeout(3000) .onSuccess([callback = std::move(callback)](auto result) -> Outcome { auto pair = parseChannelEmotes(result.parseJson()); diff --git a/src/providers/chatterino/ChatterinoBadges.cpp b/src/providers/chatterino/ChatterinoBadges.cpp index 5efde5da..ac40b4f1 100644 --- a/src/providers/chatterino/ChatterinoBadges.cpp +++ b/src/providers/chatterino/ChatterinoBadges.cpp @@ -37,7 +37,7 @@ void ChatterinoBadges::loadChatterinoBadges() static QUrl url("https://fourtf.com/chatterino/badges.json"); NetworkRequest(url) - .caller(QThread::currentThread()) + .onSuccess([this](auto result) -> Outcome { auto jsonRoot = result.parseJson(); int index = 0; diff --git a/src/providers/ffz/FfzEmotes.cpp b/src/providers/ffz/FfzEmotes.cpp index b7d3825e..e25f2600 100644 --- a/src/providers/ffz/FfzEmotes.cpp +++ b/src/providers/ffz/FfzEmotes.cpp @@ -138,7 +138,7 @@ void FfzEmotes::loadEmotes() QString url("https://api.frankerfacez.com/v1/set/global"); NetworkRequest(url) - .caller(QThread::currentThread()) + .timeout(30000) .onSuccess([this](auto result) -> Outcome { auto emotes = this->emotes(); @@ -157,7 +157,7 @@ void FfzEmotes::loadChannel(const QString &channelName, log("[FFZEmotes] Reload FFZ Channel Emotes for channel {}\n", channelName); NetworkRequest("https://api.frankerfacez.com/v1/room/" + channelName) - .caller(QThread::currentThread()) + .timeout(20000) .onSuccess([callback = std::move(callback)](auto result) -> Outcome { auto pair = parseChannelEmotes(result.parseJson()); diff --git a/src/providers/ffz/FfzModBadge.cpp b/src/providers/ffz/FfzModBadge.cpp index 2d29e95d..a41442c1 100644 --- a/src/providers/ffz/FfzModBadge.cpp +++ b/src/providers/ffz/FfzModBadge.cpp @@ -23,7 +23,7 @@ void FfzModBadge::loadCustomModBadge() QString url = partialUrl + channelName_ + "/1"; NetworkRequest(url) - .caller(QThread::currentThread()) + .onSuccess([this, url](auto result) -> Outcome { auto data = result.getData(); diff --git a/src/providers/twitch/TwitchAccount.cpp b/src/providers/twitch/TwitchAccount.cpp index 88be4685..2f1255a6 100644 --- a/src/providers/twitch/TwitchAccount.cpp +++ b/src/providers/twitch/TwitchAccount.cpp @@ -95,7 +95,7 @@ void TwitchAccount::loadIgnores() "/blocks"); NetworkRequest(url) - .caller(QThread::currentThread()) + .authorizeTwitchV5(this->getOAuthClient(), this->getOAuthToken()) .onSuccess([=](auto result) -> Outcome { auto document = result.parseRapidJson(); @@ -168,7 +168,7 @@ void TwitchAccount::ignoreByID( "/blocks/" + targetUserID); NetworkRequest(url, NetworkRequestType::Put) - .caller(QThread::currentThread()) + .authorizeTwitchV5(this->getOAuthClient(), this->getOAuthToken()) .onError([=](int errorCode) { onFinished(IgnoreResult_Failed, @@ -245,7 +245,7 @@ void TwitchAccount::unignoreByID( "/blocks/" + targetUserID); NetworkRequest(url, NetworkRequestType::Delete) - .caller(QThread::currentThread()) + .authorizeTwitchV5(this->getOAuthClient(), this->getOAuthToken()) .onError([=](int errorCode) { onFinished( @@ -279,7 +279,7 @@ void TwitchAccount::checkFollow(const QString targetUserID, "/follows/channels/" + targetUserID); NetworkRequest(url) - .caller(QThread::currentThread()) + .authorizeTwitchV5(this->getOAuthClient(), this->getOAuthToken()) .onError([=](int errorCode) { if (errorCode == 203) @@ -308,7 +308,7 @@ void TwitchAccount::followUser(const QString userID, "/follows/channels/" + userID); NetworkRequest(requestUrl, NetworkRequestType::Put) - .caller(QThread::currentThread()) + .authorizeTwitchV5(this->getOAuthClient(), this->getOAuthToken()) .onSuccess([successCallback](auto result) -> Outcome { // TODO: Properly check result of follow request @@ -326,7 +326,7 @@ void TwitchAccount::unfollowUser(const QString userID, "/follows/channels/" + userID); NetworkRequest(requestUrl, NetworkRequestType::Delete) - .caller(QThread::currentThread()) + .authorizeTwitchV5(this->getOAuthClient(), this->getOAuthToken()) .onError([successCallback](int code) { if (code >= 200 && code <= 299) @@ -368,7 +368,7 @@ void TwitchAccount::loadEmotes() "/emotes"); NetworkRequest(url) - .caller(QThread::currentThread()) + .authorizeTwitchV5(this->getOAuthClient(), this->getOAuthToken()) .onError([=](int errorCode) { log("[TwitchAccount::loadEmotes] Error {}", errorCode); @@ -409,7 +409,7 @@ void TwitchAccount::autoModAllow(const QString msgID) .header("Content-Type", "application/json") .header("Content-Length", QByteArray::number(qba.size())) .payload(qba) - .caller(QThread::currentThread()) + .authorizeTwitchV5(this->getOAuthClient(), this->getOAuthToken()) .onError([=](int errorCode) { log("[TwitchAccounts::autoModAllow] Error {}", errorCode); @@ -429,7 +429,7 @@ void TwitchAccount::autoModDeny(const QString msgID) .header("Content-Type", "application/json") .header("Content-Length", QByteArray::number(qba.size())) .payload(qba) - .caller(QThread::currentThread()) + .authorizeTwitchV5(this->getOAuthClient(), this->getOAuthToken()) .onError([=](int errorCode) { log("[TwitchAccounts::autoModDeny] Error {}", errorCode); diff --git a/src/providers/twitch/TwitchApi.cpp b/src/providers/twitch/TwitchApi.cpp index c80e9dd1..957e9132 100644 --- a/src/providers/twitch/TwitchApi.cpp +++ b/src/providers/twitch/TwitchApi.cpp @@ -16,7 +16,7 @@ void TwitchApi::findUserId(const QString user, QString requestUrl("https://api.twitch.tv/kraken/users?login=" + user); NetworkRequest(requestUrl) - .caller(QThread::currentThread()) + .authorizeTwitchV5(getDefaultClientID()) .timeout(30000) .onSuccess([successCallback](auto result) mutable -> Outcome { @@ -65,7 +65,7 @@ void TwitchApi::findUserName(const QString userid, QString requestUrl("https://api.twitch.tv/kraken/users/" + userid); NetworkRequest(requestUrl) - .caller(QThread::currentThread()) + .authorizeTwitchV5(getDefaultClientID()) .timeout(30000) .onSuccess([successCallback](auto result) mutable -> Outcome { diff --git a/src/providers/twitch/TwitchBadges.cpp b/src/providers/twitch/TwitchBadges.cpp index 4de38ec9..7fecbc91 100644 --- a/src/providers/twitch/TwitchBadges.cpp +++ b/src/providers/twitch/TwitchBadges.cpp @@ -18,7 +18,7 @@ void TwitchBadges::loadTwitchBadges() "https://badges.twitch.tv/v1/badges/global/display?language=en"); NetworkRequest(url) - .caller(QThread::currentThread()) + .onSuccess([this](auto result) -> Outcome { auto root = result.parseJson(); auto badgeSets = this->badgeSets_.access(); diff --git a/src/providers/twitch/TwitchChannel.cpp b/src/providers/twitch/TwitchChannel.cpp index 5034caa1..d6fb6a6b 100644 --- a/src/providers/twitch/TwitchChannel.cpp +++ b/src/providers/twitch/TwitchChannel.cpp @@ -502,7 +502,7 @@ void TwitchChannel::refreshLiveStatus() // auto request = makeGetStreamRequest(roomID, QThread::currentThread()); NetworkRequest::twitchRequest(url) - .caller(QThread::currentThread()) + .onSuccess( [this, weak = weakOf(this)](auto result) -> Outcome { ChannelPtr shared = weak.lock(); @@ -670,7 +670,7 @@ void TwitchChannel::refreshChatters() // get viewer list NetworkRequest("https://tmi.twitch.tv/group/user/" + this->getName() + "/chatters") - .caller(QThread::currentThread()) + .onSuccess( [this, weak = weakOf(this)](auto result) -> Outcome { // channel still exists? @@ -694,7 +694,7 @@ void TwitchChannel::refreshBadges() auto url = Url{"https://badges.twitch.tv/v1/badges/channels/" + this->roomId() + "/display?language=en"}; NetworkRequest(url.string) - .caller(QThread::currentThread()) + .onSuccess([this, weak = weakOf(this)](auto result) -> Outcome { auto shared = weak.lock(); diff --git a/src/singletons/Toasts.cpp b/src/singletons/Toasts.cpp index 813bf9e6..94e12a06 100644 --- a/src/singletons/Toasts.cpp +++ b/src/singletons/Toasts.cpp @@ -214,7 +214,7 @@ void Toasts::fetchChannelAvatar(const QString channelName, channelName); NetworkRequest(requestUrl) - .caller(QThread::currentThread()) + .authorizeTwitchV5(getDefaultClientID()) .timeout(30000) .onSuccess([successCallback](auto result) mutable -> Outcome {