#include "widgets/splits/SplitHeader.hpp" #include "Application.hpp" #include "controllers/accounts/AccountController.hpp" #include "controllers/moderationactions/ModerationActions.hpp" #include "controllers/notifications/NotificationController.hpp" #include "controllers/pings/PingController.hpp" #include "providers/twitch/TwitchChannel.hpp" #include "providers/twitch/TwitchIrcServer.hpp" #include "singletons/Resources.hpp" #include "singletons/Settings.hpp" #include "singletons/Theme.hpp" #include "singletons/TooltipPreviewImage.hpp" #include "singletons/WindowManager.hpp" #include "util/LayoutCreator.hpp" #include "util/LayoutHelper.hpp" #include "widgets/Label.hpp" #include "widgets/TooltipWidget.hpp" #include "widgets/dialogs/SettingsDialog.hpp" #include "widgets/helper/CommonTexts.hpp" #include "widgets/helper/EffectLabel.hpp" #include "widgets/splits/Split.hpp" #include "widgets/splits/SplitContainer.hpp" #include #include #include #include #include #include #include #include #include #ifdef USEWEBENGINE # include "widgets/StreamView.hpp" #endif namespace chatterino { namespace { auto formatRoomMode(TwitchChannel &channel) -> QString { QString text; { auto modes = channel.accessRoomModes(); if (modes->r9k) text += "r9k, "; if (modes->slowMode) text += QString("slow(%1), ").arg(QString::number(modes->slowMode)); if (modes->emoteOnly) text += "emote, "; if (modes->submode) text += "sub, "; if (modes->followerOnly != -1) { if (modes->followerOnly != 0) { text += QString("follow(%1m), ") .arg(QString::number(modes->followerOnly)); } else { text += QString("follow, "); } } } if (text.length() > 2) { text = text.mid(0, text.size() - 2); } if (!text.isEmpty()) { static QRegularExpression commaReplacement("^(.+?, .+?,) (.+)$"); auto match = commaReplacement.match(text); if (match.hasMatch()) text = match.captured(1) + '\n' + match.captured(2); } if (text.isEmpty() && channel.hasModRights()) return "none"; return text; } auto formatTooltip(const TwitchChannel::StreamStatus &s) { return QString(" \

%1%2%3%4%5 for %6 with %7 viewers

") .arg(s.title.toHtmlEscaped()) .arg(s.title.isEmpty() ? QString() : "

") .arg(s.game.toHtmlEscaped()) .arg(s.game.isEmpty() ? QString() : "
") .arg(s.rerun ? "Vod-casting" : "Live") .arg(s.uptime) .arg(QString::number(s.viewerCount)); } auto formatTitle(const TwitchChannel::StreamStatus &s, Settings &settings) { auto title = QString(); // live if (s.rerun) title += " (rerun)"; else if (s.streamType.isEmpty()) title += " (" + s.streamType + ")"; else title += " (live)"; // description if (settings.headerUptime) title += " - " + s.uptime; if (settings.headerViewerCount) title += " - " + QString::number(s.viewerCount); if (settings.headerGame && !s.game.isEmpty()) title += " - " + s.game; if (settings.headerStreamTitle && !s.title.isEmpty()) title += " - " + s.title; return title; } auto distance(QPoint a, QPoint b) { auto x = std::abs(a.x() - b.x()); auto y = std::abs(a.y() - b.y()); return std::sqrt(x * x + y * y); } } // namespace SplitHeader::SplitHeader(Split *_split) : BaseWidget(_split) , split_(_split) { this->initializeLayout(); this->setMouseTracking(true); this->updateChannelText(); this->handleChannelChanged(); this->updateModerationModeIcon(); this->split_->focused.connect([this]() { this->themeChangedEvent(); }); this->split_->focusLost.connect([this]() { this->themeChangedEvent(); }); this->split_->channelChanged.connect( [this]() { this->handleChannelChanged(); }); this->managedConnect(getApp()->accounts->twitch.currentUserChanged, [this] { this->updateModerationModeIcon(); }); auto _ = [this](const auto &, const auto &) { this->updateChannelText(); }; getSettings()->headerViewerCount.connect(_, this->managedConnections_); getSettings()->headerStreamTitle.connect(_, this->managedConnections_); getSettings()->headerGame.connect(_, this->managedConnections_); getSettings()->headerUptime.connect(_, this->managedConnections_); } void SplitHeader::initializeLayout() { auto layout = makeLayout({ // title this->titleLabel_ = makeWidget