diff --git a/src/providers/twitch/twitchchannel.cpp b/src/providers/twitch/twitchchannel.cpp index 61ae939a1..e6562c3a8 100644 --- a/src/providers/twitch/twitchchannel.cpp +++ b/src/providers/twitch/twitchchannel.cpp @@ -24,7 +24,6 @@ TwitchChannel::TwitchChannel(const QString &channelName, Communi::IrcConnection , subscriptionURL("https://www.twitch.tv/subs/" + name) , channelURL("https://twitch.tv/" + name) , popoutPlayerURL("https://player.twitch.tv/?channel=" + name) - , isLive(false) , mod(false) , readConnecetion(_readConnection) { @@ -176,11 +175,16 @@ void TwitchChannel::addRecentChatter(const std::shared_ptr &m void TwitchChannel::setLive(bool newLiveStatus) { - if (this->isLive == newLiveStatus) { - return; + { + std::lock_guard lock(this->streamStatusMutex); + if (this->streamStatus.live == newLiveStatus) { + // Nothing changed + return; + } + + this->streamStatus.live = newLiveStatus; } - this->isLive = newLiveStatus; this->onlineStatusChanged(); } @@ -239,13 +243,17 @@ void TwitchChannel::refreshLiveStatus() } // Stream is live - channel->streamViewerCount = QString::number(stream["viewers"].GetInt()); - channel->streamGame = stream["game"].GetString(); - channel->streamStatus = streamChannel["status"].GetString(); - QDateTime since = QDateTime::fromString(stream["created_at"].GetString(), Qt::ISODate); - auto diff = since.secsTo(QDateTime::currentDateTime()); - channel->streamUptime = - QString::number(diff / 3600) + "h " + QString::number(diff % 3600 / 60) + "m"; + + { + std::lock_guard lock(channel->streamStatusMutex); + channel->streamStatus.viewerCount = stream["viewers"].GetUint(); + channel->streamStatus.game = stream["game"].GetString(); + channel->streamStatus.title = streamChannel["status"].GetString(); + QDateTime since = QDateTime::fromString(stream["created_at"].GetString(), Qt::ISODate); + auto diff = since.secsTo(QDateTime::currentDateTime()); + channel->streamStatus.uptime = + QString::number(diff / 3600) + "h " + QString::number(diff % 3600 / 60) + "m"; + } channel->setLive(true); }); diff --git a/src/providers/twitch/twitchchannel.hpp b/src/providers/twitch/twitchchannel.hpp index 5cc5c6499..3389dea1f 100644 --- a/src/providers/twitch/twitchchannel.hpp +++ b/src/providers/twitch/twitchchannel.hpp @@ -8,6 +8,8 @@ #include "singletons/ircmanager.hpp" #include "util/concurrentmap.hpp" +#include + namespace chatterino { namespace providers { namespace twitch { @@ -20,6 +22,14 @@ class TwitchChannel final : public Channel QTimer *chattersListTimer; public: + struct StreamStatus { + bool live = false; + unsigned viewerCount = 0; + QString title; + QString game; + QString uptime; + }; + ~TwitchChannel() final; void reloadChannelEmotes(); @@ -50,23 +60,33 @@ public: boost::signals2::signal userStateChanged; QString roomID; - bool isLive; - QString streamViewerCount; - QString streamStatus; - QString streamGame; - QString streamUptime; + + StreamStatus GetStreamStatus() const + { + std::lock_guard lock(this->streamStatusMutex); + return this->streamStatus; + } struct NameOptions { QString displayName; QString localizedName; }; + bool IsLive() const + { + std::lock_guard lock(this->streamStatusMutex); + return this->streamStatus.live; + } + private: explicit TwitchChannel(const QString &channelName, Communi::IrcConnection *readConnection); void setLive(bool newLiveStatus); void refreshLiveStatus(); + mutable std::mutex streamStatusMutex; + StreamStatus streamStatus; + void fetchRecentMessages(); boost::signals2::connection connectedConnection; diff --git a/src/singletons/commandmanager.cpp b/src/singletons/commandmanager.cpp index 60deb66a5..3c561ec38 100644 --- a/src/singletons/commandmanager.cpp +++ b/src/singletons/commandmanager.cpp @@ -112,8 +112,10 @@ QString CommandManager::execCommand(const QString &text, ChannelPtr channel, boo if (!dryRun && twitchChannel != nullptr) { if (commandName == "/uptime") { + const auto &streamStatus = twitchChannel->GetStreamStatus(); + QString messageText = - twitchChannel->isLive ? twitchChannel->streamUptime : "Channel is not live."; + streamStatus.live ? streamStatus.uptime : "Channel is not live."; channel->addMessage(messages::Message::createSystemMessage(messageText)); diff --git a/src/widgets/helper/splitheader.cpp b/src/widgets/helper/splitheader.cpp index ca43da27f..2942f137b 100644 --- a/src/widgets/helper/splitheader.cpp +++ b/src/widgets/helper/splitheader.cpp @@ -157,29 +157,36 @@ void SplitHeader::updateChannelText() const QString channelName = this->split->channelName; if (channelName.isEmpty()) { this->titleLabel->setText(""); - } else { - auto channel = this->split->getChannel(); + return; + } - TwitchChannel *twitchChannel = dynamic_cast(channel.get()); + auto channel = this->split->getChannel(); - if (twitchChannel != nullptr && twitchChannel->isLive) { + TwitchChannel *twitchChannel = dynamic_cast(channel.get()); + + if (twitchChannel != nullptr) { + const auto &streamStatus = twitchChannel->GetStreamStatus(); + + if (streamStatus.live) { this->isLive = true; this->tooltip = "" "

" + - twitchChannel->streamStatus + "

" + twitchChannel->streamGame + + streamStatus.title + "

" + streamStatus.game + "
" "Live for " + - twitchChannel->streamUptime + " with " + - twitchChannel->streamViewerCount + + streamStatus.uptime + " with " + + QString::number(streamStatus.viewerCount) + " viewers" "

"; this->titleLabel->setText(channelName + " (live)"); - } else { - this->isLive = false; - this->titleLabel->setText(channelName); - this->tooltip = ""; + + return; } } + + this->isLive = false; + this->titleLabel->setText(channelName); + this->tooltip = ""; } void SplitHeader::updateModerationModeIcon()