2018-06-26 14:39:22 +02:00
|
|
|
#include "widgets/splits/SplitHeader.hpp"
|
2018-04-28 15:20:18 +02:00
|
|
|
|
2018-06-26 14:09:39 +02:00
|
|
|
#include "Application.hpp"
|
2018-07-07 13:08:57 +02:00
|
|
|
#include "controllers/accounts/AccountController.hpp"
|
2018-08-09 15:41:03 +02:00
|
|
|
#include "controllers/notifications/NotificationController.hpp"
|
2018-06-26 14:09:39 +02:00
|
|
|
#include "providers/twitch/TwitchChannel.hpp"
|
2019-09-15 13:02:02 +02:00
|
|
|
#include "providers/twitch/TwitchIrcServer.hpp"
|
2018-06-28 19:46:45 +02:00
|
|
|
#include "singletons/Resources.hpp"
|
2018-08-11 22:23:06 +02:00
|
|
|
#include "singletons/Settings.hpp"
|
2018-06-28 20:03:04 +02:00
|
|
|
#include "singletons/Theme.hpp"
|
2019-06-22 16:39:59 +02:00
|
|
|
#include "singletons/TooltipPreviewImage.hpp"
|
2018-10-21 15:32:28 +02:00
|
|
|
#include "singletons/WindowManager.hpp"
|
2021-03-06 15:03:33 +01:00
|
|
|
#include "util/Helpers.hpp"
|
2018-06-26 14:09:39 +02:00
|
|
|
#include "util/LayoutCreator.hpp"
|
2018-08-08 15:35:54 +02:00
|
|
|
#include "util/LayoutHelper.hpp"
|
2020-10-11 13:52:14 +02:00
|
|
|
#include "util/StreamerMode.hpp"
|
2018-06-26 14:09:39 +02:00
|
|
|
#include "widgets/Label.hpp"
|
2018-06-26 17:20:03 +02:00
|
|
|
#include "widgets/TooltipWidget.hpp"
|
2018-10-21 15:32:28 +02:00
|
|
|
#include "widgets/dialogs/SettingsDialog.hpp"
|
2019-04-27 10:12:51 +02:00
|
|
|
#include "widgets/helper/CommonTexts.hpp"
|
2018-08-11 22:23:06 +02:00
|
|
|
#include "widgets/helper/EffectLabel.hpp"
|
2018-06-26 14:39:22 +02:00
|
|
|
#include "widgets/splits/Split.hpp"
|
|
|
|
#include "widgets/splits/SplitContainer.hpp"
|
2017-01-01 02:30:42 +01:00
|
|
|
|
2018-08-07 09:05:27 +02:00
|
|
|
#include <QDesktopWidget>
|
2017-01-15 16:38:30 +01:00
|
|
|
#include <QDrag>
|
2018-08-11 22:23:06 +02:00
|
|
|
#include <QHBoxLayout>
|
2018-06-24 12:22:50 +02:00
|
|
|
#include <QInputDialog>
|
2018-08-07 23:46:00 +02:00
|
|
|
#include <QMenu>
|
2017-01-15 16:38:30 +01:00
|
|
|
#include <QMimeData>
|
|
|
|
#include <QPainter>
|
2018-08-08 15:35:54 +02:00
|
|
|
#include <cmath>
|
2017-01-15 16:38:30 +01:00
|
|
|
|
2018-01-19 14:48:17 +01:00
|
|
|
#ifdef USEWEBENGINE
|
2018-08-15 22:46:20 +02:00
|
|
|
# include "widgets/StreamView.hpp"
|
2018-01-19 14:48:17 +01:00
|
|
|
#endif
|
|
|
|
|
2017-04-14 17:52:22 +02:00
|
|
|
namespace chatterino {
|
2018-08-08 15:35:54 +02:00
|
|
|
namespace {
|
2018-08-15 22:46:20 +02:00
|
|
|
auto formatRoomMode(TwitchChannel &channel) -> QString
|
2018-01-13 04:05:38 +01:00
|
|
|
{
|
2018-08-15 22:46:20 +02:00
|
|
|
QString text;
|
2018-01-14 22:24:21 +01:00
|
|
|
|
2018-08-15 22:46:20 +02:00
|
|
|
{
|
|
|
|
auto modes = channel.accessRoomModes();
|
2018-06-24 12:22:50 +02:00
|
|
|
|
2018-10-21 13:43:02 +02:00
|
|
|
if (modes->r9k)
|
|
|
|
text += "r9k, ";
|
2018-08-15 22:46:20 +02:00
|
|
|
if (modes->slowMode)
|
|
|
|
text +=
|
2021-03-06 15:03:33 +01:00
|
|
|
QString("slow(%1), ").arg(localizeNumbers(modes->slowMode));
|
2018-10-21 13:43:02 +02:00
|
|
|
if (modes->emoteOnly)
|
|
|
|
text += "emote, ";
|
|
|
|
if (modes->submode)
|
|
|
|
text += "sub, ";
|
2019-08-25 19:08:04 +02:00
|
|
|
if (modes->followerOnly != -1)
|
|
|
|
{
|
|
|
|
if (modes->followerOnly != 0)
|
|
|
|
{
|
2019-08-26 13:48:07 +02:00
|
|
|
text += QString("follow(%1m), ")
|
2021-03-06 15:03:33 +01:00
|
|
|
.arg(localizeNumbers(modes->followerOnly));
|
2019-08-25 19:08:04 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-08-26 13:48:07 +02:00
|
|
|
text += QString("follow, ");
|
2019-08-25 19:08:04 +02:00
|
|
|
}
|
|
|
|
}
|
2018-08-15 22:46:20 +02:00
|
|
|
}
|
2018-05-24 08:58:34 +02:00
|
|
|
|
2018-10-21 13:43:02 +02:00
|
|
|
if (text.length() > 2)
|
|
|
|
{
|
2018-08-15 22:46:20 +02:00
|
|
|
text = text.mid(0, text.size() - 2);
|
|
|
|
}
|
2018-07-04 19:43:41 +02:00
|
|
|
|
2018-10-21 13:43:02 +02:00
|
|
|
if (!text.isEmpty())
|
|
|
|
{
|
2018-08-15 22:46:20 +02:00
|
|
|
static QRegularExpression commaReplacement("^(.+?, .+?,) (.+)$");
|
2018-05-24 08:58:34 +02:00
|
|
|
|
2018-08-15 22:46:20 +02:00
|
|
|
auto match = commaReplacement.match(text);
|
|
|
|
if (match.hasMatch())
|
|
|
|
text = match.captured(1) + '\n' + match.captured(2);
|
|
|
|
}
|
2018-01-17 16:52:51 +01:00
|
|
|
|
2018-10-21 13:43:02 +02:00
|
|
|
if (text.isEmpty() && channel.hasModRights())
|
|
|
|
return "none";
|
2018-07-04 13:05:54 +02:00
|
|
|
|
2018-08-15 22:46:20 +02:00
|
|
|
return text;
|
|
|
|
}
|
2020-05-24 11:57:15 +02:00
|
|
|
auto formatTooltip(const TwitchChannel::StreamStatus &s, QString thumbnail)
|
2018-08-15 22:46:20 +02:00
|
|
|
{
|
2020-10-11 13:52:14 +02:00
|
|
|
auto title = [&s]() -> QString {
|
|
|
|
if (s.title.isEmpty())
|
|
|
|
{
|
|
|
|
return QStringLiteral("");
|
|
|
|
}
|
|
|
|
|
|
|
|
return s.title.toHtmlEscaped() + "<br><br>";
|
|
|
|
}();
|
|
|
|
|
|
|
|
auto tooltip = [&thumbnail]() -> QString {
|
|
|
|
if (getSettings()->thumbnailSizeStream.getValue() == 0)
|
|
|
|
{
|
|
|
|
return QStringLiteral("");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (thumbnail.isEmpty())
|
|
|
|
{
|
|
|
|
return QStringLiteral("Couldn't fetch thumbnail<br>");
|
|
|
|
}
|
|
|
|
|
|
|
|
return "<img src=\"data:image/jpg;base64, " + thumbnail + "\"><br>";
|
|
|
|
}();
|
|
|
|
|
|
|
|
auto game = [&s]() -> QString {
|
|
|
|
if (s.game.isEmpty())
|
|
|
|
{
|
|
|
|
return QStringLiteral("");
|
|
|
|
}
|
|
|
|
|
|
|
|
return s.game.toHtmlEscaped() + "<br>";
|
|
|
|
}();
|
|
|
|
|
|
|
|
auto extraStreamData = [&s]() -> QString {
|
|
|
|
if (isInStreamerMode() &&
|
|
|
|
getSettings()->streamerModeHideViewerCountAndDuration)
|
|
|
|
{
|
|
|
|
return QStringLiteral(
|
|
|
|
"<span style=\"color: #808892;\"><Streamer "
|
|
|
|
"Mode></span>");
|
|
|
|
}
|
|
|
|
|
|
|
|
return QString("%1 for %2 with %3 viewers")
|
|
|
|
.arg(s.rerun ? "Vod-casting" : "Live")
|
|
|
|
.arg(s.uptime)
|
2021-03-06 15:03:33 +01:00
|
|
|
.arg(localizeNumbers(s.viewerCount));
|
2020-10-11 13:52:14 +02:00
|
|
|
}();
|
|
|
|
|
|
|
|
return QString("<p style=\"text-align: center;\">" + //
|
|
|
|
title + //
|
|
|
|
tooltip + //
|
|
|
|
game + //
|
|
|
|
extraStreamData + //
|
|
|
|
"</p>" //
|
|
|
|
);
|
2018-08-15 22:46:20 +02:00
|
|
|
}
|
2019-10-12 15:09:12 +02:00
|
|
|
auto formatOfflineTooltip(const TwitchChannel::StreamStatus &s)
|
|
|
|
{
|
2020-10-11 13:52:14 +02:00
|
|
|
return QString("<p style=\"text-align: center;\">Offline<br>%1</p>")
|
2019-10-12 15:09:12 +02:00
|
|
|
.arg(s.title.toHtmlEscaped());
|
|
|
|
}
|
2018-08-15 22:46:20 +02:00
|
|
|
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
|
2018-10-31 19:45:51 +01:00
|
|
|
if (settings.headerUptime)
|
2018-10-21 13:43:02 +02:00
|
|
|
title += " - " + s.uptime;
|
2018-10-31 19:45:51 +01:00
|
|
|
if (settings.headerViewerCount)
|
2021-03-06 15:03:33 +01:00
|
|
|
title += " - " + localizeNumbers(s.viewerCount);
|
2019-08-16 22:40:30 +02:00
|
|
|
if (settings.headerGame && !s.game.isEmpty())
|
2018-10-21 13:43:02 +02:00
|
|
|
title += " - " + s.game;
|
2019-08-16 22:40:30 +02:00
|
|
|
if (settings.headerStreamTitle && !s.title.isEmpty())
|
2021-05-09 11:22:20 +02:00
|
|
|
{
|
|
|
|
title += " - " + s.title.simplified();
|
|
|
|
}
|
2018-08-15 22:46:20 +02:00
|
|
|
|
|
|
|
return title;
|
|
|
|
}
|
|
|
|
auto distance(QPoint a, QPoint b)
|
|
|
|
{
|
|
|
|
auto x = std::abs(a.x() - b.x());
|
|
|
|
auto y = std::abs(a.y() - b.y());
|
2018-01-17 16:52:51 +01:00
|
|
|
|
2018-08-15 22:46:20 +02:00
|
|
|
return std::sqrt(x * x + y * y);
|
2018-01-13 04:05:38 +01:00
|
|
|
}
|
2018-08-08 15:35:54 +02:00
|
|
|
} // namespace
|
2018-01-13 04:05:38 +01:00
|
|
|
|
2018-08-08 15:35:54 +02:00
|
|
|
SplitHeader::SplitHeader(Split *_split)
|
|
|
|
: BaseWidget(_split)
|
|
|
|
, split_(_split)
|
|
|
|
{
|
|
|
|
this->initializeLayout();
|
2017-07-02 14:28:37 +02:00
|
|
|
|
2018-08-08 15:35:54 +02:00
|
|
|
this->setMouseTracking(true);
|
2017-06-11 09:11:55 +02:00
|
|
|
this->updateChannelText();
|
2018-08-08 15:35:54 +02:00
|
|
|
this->handleChannelChanged();
|
|
|
|
this->updateModerationModeIcon();
|
2017-01-15 16:38:30 +01:00
|
|
|
|
2020-11-08 12:02:19 +01:00
|
|
|
this->split_->focused.connect([this]() {
|
|
|
|
this->themeChangedEvent();
|
|
|
|
});
|
|
|
|
this->split_->focusLost.connect([this]() {
|
|
|
|
this->themeChangedEvent();
|
|
|
|
});
|
|
|
|
this->split_->channelChanged.connect([this]() {
|
|
|
|
this->handleChannelChanged();
|
|
|
|
});
|
2018-05-26 16:31:43 +02:00
|
|
|
|
2020-11-08 12:02:19 +01:00
|
|
|
this->managedConnect(getApp()->accounts->twitch.currentUserChanged, [this] {
|
|
|
|
this->updateModerationModeIcon();
|
|
|
|
});
|
2018-05-26 17:20:16 +02:00
|
|
|
|
2020-11-08 12:02:19 +01:00
|
|
|
auto _ = [this](const auto &, const auto &) {
|
|
|
|
this->updateChannelText();
|
|
|
|
};
|
2018-10-31 19:45:51 +01:00
|
|
|
getSettings()->headerViewerCount.connect(_, this->managedConnections_);
|
|
|
|
getSettings()->headerStreamTitle.connect(_, this->managedConnections_);
|
|
|
|
getSettings()->headerGame.connect(_, this->managedConnections_);
|
|
|
|
getSettings()->headerUptime.connect(_, this->managedConnections_);
|
2017-11-04 14:57:29 +01:00
|
|
|
}
|
|
|
|
|
2018-08-08 15:35:54 +02:00
|
|
|
void SplitHeader::initializeLayout()
|
2018-01-13 04:05:38 +01:00
|
|
|
{
|
2018-09-04 21:39:54 +02:00
|
|
|
auto layout = makeLayout<QHBoxLayout>({
|
2020-09-25 23:41:18 +02:00
|
|
|
// space
|
2020-11-08 12:02:19 +01:00
|
|
|
makeWidget<BaseWidget>([](auto w) {
|
|
|
|
w->setScaleIndependantSize(8, 4);
|
|
|
|
}),
|
2018-09-04 21:39:54 +02:00
|
|
|
// title
|
|
|
|
this->titleLabel_ = makeWidget<Label>([](auto w) {
|
|
|
|
w->setSizePolicy(QSizePolicy::MinimumExpanding,
|
|
|
|
QSizePolicy::Preferred);
|
|
|
|
w->setCentered(true);
|
|
|
|
w->setHasOffset(false);
|
|
|
|
}),
|
2020-09-25 23:41:18 +02:00
|
|
|
// space
|
2020-11-08 12:02:19 +01:00
|
|
|
makeWidget<BaseWidget>([](auto w) {
|
|
|
|
w->setScaleIndependantSize(8, 4);
|
|
|
|
}),
|
2018-09-04 21:39:54 +02:00
|
|
|
// mode
|
|
|
|
this->modeButton_ = makeWidget<EffectLabel>([&](auto w) {
|
|
|
|
w->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
|
|
|
w->hide();
|
|
|
|
this->initializeModeSignals(*w);
|
|
|
|
w->setMenu(this->createChatModeMenu());
|
|
|
|
}),
|
|
|
|
// moderator
|
|
|
|
this->moderationButton_ = makeWidget<Button>([&](auto w) {
|
2018-10-21 16:13:26 +02:00
|
|
|
QObject::connect(
|
|
|
|
w, &Button::clicked, this,
|
|
|
|
[this, w](Qt::MouseButton button) mutable {
|
|
|
|
switch (button)
|
2018-10-21 15:32:28 +02:00
|
|
|
{
|
2018-10-21 16:13:26 +02:00
|
|
|
case Qt::LeftButton:
|
2020-02-23 23:07:28 +01:00
|
|
|
if (getSettings()->moderationActions.empty())
|
2018-10-21 16:13:26 +02:00
|
|
|
{
|
|
|
|
getApp()->windows->showSettingsDialog(
|
2020-10-31 16:42:48 +01:00
|
|
|
this, SettingsDialogPreference::
|
|
|
|
ModerationActions);
|
2018-10-21 16:13:26 +02:00
|
|
|
this->split_->setModerationMode(true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
auto moderationMode =
|
|
|
|
this->split_->getModerationMode();
|
|
|
|
|
|
|
|
this->split_->setModerationMode(
|
|
|
|
!moderationMode);
|
2019-09-01 13:06:56 +02:00
|
|
|
w->setDim(Button::Dim(moderationMode));
|
2018-10-21 16:13:26 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Qt::RightButton:
|
|
|
|
case Qt::MiddleButton:
|
|
|
|
getApp()->windows->showSettingsDialog(
|
2020-10-31 16:42:48 +01:00
|
|
|
this,
|
2018-10-21 16:13:26 +02:00
|
|
|
SettingsDialogPreference::ModerationActions);
|
|
|
|
break;
|
2018-10-21 15:32:28 +02:00
|
|
|
}
|
2018-10-21 16:13:26 +02:00
|
|
|
});
|
2018-09-04 21:39:54 +02:00
|
|
|
}),
|
2020-10-10 17:24:53 +02:00
|
|
|
// viewer list
|
|
|
|
this->viewersButton_ = makeWidget<Button>([&](auto w) {
|
2020-11-08 12:02:19 +01:00
|
|
|
QObject::connect(w, &Button::leftClicked, this, [this]() {
|
|
|
|
this->split_->showViewerList();
|
|
|
|
});
|
2020-10-10 17:24:53 +02:00
|
|
|
}),
|
2018-09-04 21:39:54 +02:00
|
|
|
// dropdown
|
2019-07-13 12:17:22 +02:00
|
|
|
this->dropdownButton_ = makeWidget<Button>([&](auto w) {
|
2019-09-11 13:34:59 +02:00
|
|
|
/// XXX: this never gets disconnected
|
2021-04-03 17:33:51 +02:00
|
|
|
QObject::connect(w, &Button::leftMousePress, this, [this] {
|
2019-10-12 11:17:40 +02:00
|
|
|
this->dropdownButton_->setMenu(this->createMainMenu());
|
2019-09-11 13:34:59 +02:00
|
|
|
});
|
2019-07-13 12:17:22 +02:00
|
|
|
}),
|
2018-09-04 21:39:54 +02:00
|
|
|
// add split
|
|
|
|
this->addButton_ = makeWidget<Button>([&](auto w) {
|
2019-09-22 10:53:39 +02:00
|
|
|
w->setPixmap(getResources().buttons.addSplitDark);
|
2018-09-04 21:39:54 +02:00
|
|
|
w->setEnableMargin(false);
|
|
|
|
|
2020-11-08 12:02:19 +01:00
|
|
|
QObject::connect(w, &Button::leftClicked, this, [this]() {
|
|
|
|
this->split_->addSibling();
|
|
|
|
});
|
2018-09-04 21:39:54 +02:00
|
|
|
}),
|
|
|
|
});
|
2018-08-08 15:35:54 +02:00
|
|
|
|
2018-10-21 16:13:26 +02:00
|
|
|
// update moderation button when items changed
|
2020-02-23 23:07:28 +01:00
|
|
|
this->managedConnect(getSettings()->moderationActions.delayedItemsChanged,
|
2019-08-11 21:08:18 +02:00
|
|
|
[this] {
|
2020-02-23 23:07:28 +01:00
|
|
|
if (getSettings()->moderationActions.empty())
|
2019-08-11 21:08:18 +02:00
|
|
|
{
|
|
|
|
if (this->split_->getModerationMode())
|
|
|
|
this->split_->setModerationMode(true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (this->split_->getModerationMode())
|
|
|
|
this->split_->setModerationMode(true);
|
|
|
|
}
|
|
|
|
});
|
2018-10-21 16:13:26 +02:00
|
|
|
|
2021-04-17 11:55:44 +02:00
|
|
|
getSettings()->customURIScheme.connect(
|
|
|
|
[this] {
|
|
|
|
if (const auto drop = this->dropdownButton_)
|
|
|
|
{
|
|
|
|
drop->setMenu(this->createMainMenu());
|
|
|
|
}
|
|
|
|
},
|
|
|
|
this->managedConnections_);
|
2020-04-11 11:43:35 +02:00
|
|
|
|
2018-08-08 15:35:54 +02:00
|
|
|
layout->setMargin(0);
|
|
|
|
layout->setSpacing(0);
|
|
|
|
this->setLayout(layout);
|
2018-10-07 19:25:46 +02:00
|
|
|
|
|
|
|
this->setAddButtonVisible(false);
|
2018-01-13 04:05:38 +01:00
|
|
|
}
|
|
|
|
|
2018-08-07 23:46:00 +02:00
|
|
|
std::unique_ptr<QMenu> SplitHeader::createMainMenu()
|
2018-01-13 04:05:38 +01:00
|
|
|
{
|
2018-10-09 19:04:18 +02:00
|
|
|
// top level menu
|
2018-08-07 23:46:00 +02:00
|
|
|
auto menu = std::make_unique<QMenu>();
|
2018-08-08 15:35:54 +02:00
|
|
|
menu->addAction("Change channel", this->split_, &Split::changeChannel,
|
|
|
|
QKeySequence("Ctrl+R"));
|
2018-10-09 18:28:40 +02:00
|
|
|
menu->addAction("Close", this->split_, &Split::deleteFromContainer,
|
|
|
|
QKeySequence("Ctrl+W"));
|
2018-08-07 23:46:00 +02:00
|
|
|
menu->addSeparator();
|
2020-08-13 18:02:23 +02:00
|
|
|
menu->addAction("Popup", this->split_, &Split::popup,
|
|
|
|
QKeySequence("Ctrl+N"));
|
2018-08-08 15:35:54 +02:00
|
|
|
menu->addAction("Search", this->split_, &Split::showSearch,
|
|
|
|
QKeySequence("Ctrl+F"));
|
2020-10-18 15:16:56 +02:00
|
|
|
menu->addAction("Set filters", this->split_, &Split::setFiltersDialog);
|
2018-08-07 23:46:00 +02:00
|
|
|
menu->addSeparator();
|
2018-01-19 14:48:17 +01:00
|
|
|
#ifdef USEWEBENGINE
|
2018-08-07 23:46:00 +02:00
|
|
|
this->dropdownMenu.addAction("Start watching", this, [this] {
|
2018-01-24 13:15:41 +01:00
|
|
|
ChannelPtr _channel = this->split->getChannel();
|
2018-02-05 15:11:50 +01:00
|
|
|
TwitchChannel *tc = dynamic_cast<TwitchChannel *>(_channel.get());
|
2018-01-19 14:48:17 +01:00
|
|
|
|
2018-10-21 13:43:02 +02:00
|
|
|
if (tc != nullptr)
|
|
|
|
{
|
2018-08-07 23:46:00 +02:00
|
|
|
StreamView *view = new StreamView(
|
2020-06-12 19:44:05 +02:00
|
|
|
_channel,
|
|
|
|
"https://player.twitch.tv/?parent=twitch.tv&channel=" +
|
|
|
|
tc->name);
|
2018-01-19 14:48:17 +01:00
|
|
|
view->setAttribute(Qt::WA_DeleteOnClose, true);
|
|
|
|
view->show();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
#endif
|
2018-10-09 19:04:18 +02:00
|
|
|
|
2021-01-17 14:47:34 +01:00
|
|
|
auto *twitchChannel =
|
|
|
|
dynamic_cast<TwitchChannel *>(this->split_->getChannel().get());
|
|
|
|
|
|
|
|
if (twitchChannel)
|
2019-09-11 13:34:59 +02:00
|
|
|
{
|
|
|
|
menu->addAction(OPEN_IN_BROWSER, this->split_, &Split::openInBrowser);
|
2018-01-19 14:48:17 +01:00
|
|
|
#ifndef USEWEBENGINE
|
2019-09-11 13:34:59 +02:00
|
|
|
menu->addAction(OPEN_PLAYER_IN_BROWSER, this->split_,
|
|
|
|
&Split::openBrowserPlayer);
|
2018-01-19 14:48:17 +01:00
|
|
|
#endif
|
2019-09-11 13:34:59 +02:00
|
|
|
menu->addAction(OPEN_IN_STREAMLINK, this->split_,
|
|
|
|
&Split::openInStreamlink);
|
2020-04-11 11:43:35 +02:00
|
|
|
|
|
|
|
if (!getSettings()->customURIScheme.getValue().isEmpty())
|
|
|
|
{
|
2020-08-22 15:01:16 +02:00
|
|
|
menu->addAction("Open in custom player", this->split_,
|
2020-04-11 11:43:35 +02:00
|
|
|
&Split::openWithCustomScheme);
|
|
|
|
}
|
2021-01-02 17:25:27 +01:00
|
|
|
|
|
|
|
if (this->split_->getChannel()->hasModRights())
|
|
|
|
{
|
|
|
|
menu->addAction(OPEN_MOD_VIEW_IN_BROWSER, this->split_,
|
|
|
|
&Split::openModViewInBrowser);
|
|
|
|
}
|
|
|
|
|
2021-01-18 15:11:50 +01:00
|
|
|
menu->addAction(
|
|
|
|
"Create a clip", this->split_,
|
|
|
|
[twitchChannel] {
|
|
|
|
twitchChannel->createClip();
|
|
|
|
},
|
|
|
|
QKeySequence("Alt+X"))
|
|
|
|
->setVisible(twitchChannel->isLive());
|
|
|
|
|
2019-09-11 13:34:59 +02:00
|
|
|
menu->addSeparator();
|
2020-08-08 15:17:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (this->split_->getChannel()->getType() == Channel::Type::TwitchWhispers)
|
|
|
|
{
|
2020-08-15 10:15:57 +02:00
|
|
|
menu->addAction(OPEN_WHISPERS_IN_BROWSER, this->split_,
|
2020-08-08 15:17:51 +02:00
|
|
|
&Split::openWhispersInBrowser);
|
|
|
|
menu->addSeparator();
|
2019-09-11 13:34:59 +02:00
|
|
|
}
|
2018-10-09 19:04:18 +02:00
|
|
|
|
2020-08-13 18:02:23 +02:00
|
|
|
// reload / reconnect
|
|
|
|
if (this->split_->getChannel()->canReconnect())
|
2020-11-22 14:28:07 +01:00
|
|
|
{
|
|
|
|
menu->addAction("Reconnect", this, SLOT(reconnect()),
|
|
|
|
QKeySequence("Ctrl+F5"));
|
|
|
|
}
|
2020-08-13 18:02:23 +02:00
|
|
|
|
2021-01-17 14:47:34 +01:00
|
|
|
if (twitchChannel)
|
2020-08-13 18:02:23 +02:00
|
|
|
{
|
|
|
|
menu->addAction("Reload channel emotes", this,
|
|
|
|
SLOT(reloadChannelEmotes()), QKeySequence("F5"));
|
|
|
|
menu->addAction("Reload subscriber emotes", this,
|
2020-08-13 20:59:57 +02:00
|
|
|
SLOT(reloadSubscriberEmotes()), QKeySequence("F5"));
|
2020-08-13 18:02:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
menu->addSeparator();
|
|
|
|
|
2019-07-21 13:01:35 +02:00
|
|
|
{
|
|
|
|
// "How to..." sub menu
|
|
|
|
auto subMenu = new QMenu("How to...", this);
|
|
|
|
subMenu->addAction("move split", this->split_, &Split::explainMoving);
|
|
|
|
subMenu->addAction("add/split", this->split_, &Split::explainSplitting);
|
|
|
|
menu->addMenu(subMenu);
|
|
|
|
}
|
|
|
|
|
2020-08-13 18:02:23 +02:00
|
|
|
menu->addSeparator();
|
|
|
|
|
2018-10-09 19:04:18 +02:00
|
|
|
// sub menu
|
|
|
|
auto moreMenu = new QMenu("More", this);
|
2019-07-16 21:59:04 +02:00
|
|
|
|
2019-09-16 11:44:03 +02:00
|
|
|
moreMenu->addAction("Toggle moderation mode", this->split_, [this]() {
|
|
|
|
this->split_->setModerationMode(!this->split_->getModerationMode());
|
|
|
|
});
|
|
|
|
|
2021-01-16 14:27:19 +01:00
|
|
|
if (this->split_->getChannel()->getType() == Channel::Type::TwitchMentions)
|
|
|
|
{
|
|
|
|
auto action = new QAction(this);
|
|
|
|
action->setText("Enable /mention tab highlights");
|
|
|
|
action->setCheckable(true);
|
|
|
|
|
|
|
|
QObject::connect(moreMenu, &QMenu::aboutToShow, this, [action, this]() {
|
|
|
|
action->setChecked(getSettings()->highlightMentions);
|
|
|
|
});
|
|
|
|
action->connect(action, &QAction::triggered, this, [this]() {
|
|
|
|
getSettings()->highlightMentions =
|
|
|
|
!getSettings()->highlightMentions;
|
|
|
|
});
|
|
|
|
|
|
|
|
moreMenu->addAction(action);
|
|
|
|
}
|
|
|
|
|
2021-01-17 14:47:34 +01:00
|
|
|
if (twitchChannel)
|
2019-09-11 13:34:59 +02:00
|
|
|
{
|
|
|
|
moreMenu->addAction("Show viewer list", this->split_,
|
|
|
|
&Split::showViewerList);
|
2018-08-09 15:41:03 +02:00
|
|
|
|
2019-09-11 13:34:59 +02:00
|
|
|
moreMenu->addAction("Subscribe", this->split_, &Split::openSubPage);
|
2019-07-16 21:59:04 +02:00
|
|
|
|
2019-09-11 13:34:59 +02:00
|
|
|
auto action = new QAction(this);
|
|
|
|
action->setText("Notify when live");
|
|
|
|
action->setCheckable(true);
|
2018-08-12 15:29:40 +02:00
|
|
|
|
2019-09-11 13:34:59 +02:00
|
|
|
QObject::connect(moreMenu, &QMenu::aboutToShow, this, [action, this]() {
|
|
|
|
action->setChecked(getApp()->notifications->isChannelNotified(
|
|
|
|
this->split_->getChannel()->getName(), Platform::Twitch));
|
|
|
|
});
|
|
|
|
action->connect(action, &QAction::triggered, this, [this]() {
|
|
|
|
getApp()->notifications->updateChannelNotification(
|
|
|
|
this->split_->getChannel()->getName(), Platform::Twitch);
|
|
|
|
});
|
2018-08-24 18:05:36 +02:00
|
|
|
|
2019-09-11 13:34:59 +02:00
|
|
|
moreMenu->addAction(action);
|
|
|
|
}
|
2018-10-09 19:04:18 +02:00
|
|
|
|
2021-01-17 14:47:34 +01:00
|
|
|
if (twitchChannel)
|
2019-05-10 22:36:37 +02:00
|
|
|
{
|
|
|
|
auto action = new QAction(this);
|
|
|
|
action->setText("Mute highlight sound");
|
|
|
|
action->setCheckable(true);
|
|
|
|
|
|
|
|
QObject::connect(moreMenu, &QMenu::aboutToShow, this, [action, this]() {
|
2020-02-23 23:07:28 +01:00
|
|
|
action->setChecked(getSettings()->isMutedChannel(
|
2019-05-10 22:36:37 +02:00
|
|
|
this->split_->getChannel()->getName()));
|
|
|
|
});
|
|
|
|
action->connect(action, &QAction::triggered, this, [this]() {
|
2020-02-23 23:07:28 +01:00
|
|
|
getSettings()->toggleMutedChannel(
|
|
|
|
this->split_->getChannel()->getName());
|
2019-05-10 22:36:37 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
moreMenu->addAction(action);
|
|
|
|
}
|
|
|
|
|
2018-10-09 19:04:18 +02:00
|
|
|
moreMenu->addSeparator();
|
|
|
|
moreMenu->addAction("Clear messages", this->split_, &Split::clear);
|
|
|
|
// moreMenu->addSeparator();
|
|
|
|
// moreMenu->addAction("Show changelog", this,
|
|
|
|
// SLOT(moreMenuShowChangelog()));
|
|
|
|
menu->addMenu(moreMenu);
|
2018-08-07 23:46:00 +02:00
|
|
|
|
|
|
|
return menu;
|
2018-07-04 13:05:54 +02:00
|
|
|
}
|
|
|
|
|
2018-08-07 23:46:00 +02:00
|
|
|
std::unique_ptr<QMenu> SplitHeader::createChatModeMenu()
|
2018-07-04 19:43:41 +02:00
|
|
|
{
|
2018-08-07 23:46:00 +02:00
|
|
|
auto menu = std::make_unique<QMenu>();
|
2018-07-04 19:43:41 +02:00
|
|
|
|
2018-07-04 13:05:54 +02:00
|
|
|
auto setSub = new QAction("Subscriber only", this);
|
|
|
|
auto setEmote = new QAction("Emote only", this);
|
|
|
|
auto setSlow = new QAction("Slow", this);
|
|
|
|
auto setR9k = new QAction("R9K", this);
|
2019-08-25 19:08:04 +02:00
|
|
|
auto setFollowers = new QAction("Followers only", this);
|
2018-07-04 13:05:54 +02:00
|
|
|
|
2019-08-25 19:08:04 +02:00
|
|
|
setFollowers->setCheckable(true);
|
2018-07-04 19:43:41 +02:00
|
|
|
setSub->setCheckable(true);
|
|
|
|
setEmote->setCheckable(true);
|
|
|
|
setSlow->setCheckable(true);
|
|
|
|
setR9k->setCheckable(true);
|
|
|
|
|
2018-08-07 23:46:00 +02:00
|
|
|
menu->addAction(setEmote);
|
|
|
|
menu->addAction(setSub);
|
|
|
|
menu->addAction(setSlow);
|
|
|
|
menu->addAction(setR9k);
|
2019-08-25 19:08:04 +02:00
|
|
|
menu->addAction(setFollowers);
|
2018-07-04 13:05:54 +02:00
|
|
|
|
2020-11-08 12:02:19 +01:00
|
|
|
this->managedConnections_.push_back(this->modeUpdateRequested_.connect(
|
2019-08-25 19:08:04 +02:00
|
|
|
[this, setSub, setEmote, setSlow, setR9k, setFollowers]() {
|
2018-08-06 21:17:03 +02:00
|
|
|
auto twitchChannel =
|
|
|
|
dynamic_cast<TwitchChannel *>(this->split_->getChannel().get());
|
2018-10-21 13:43:02 +02:00
|
|
|
if (twitchChannel == nullptr)
|
|
|
|
{
|
2018-07-06 19:23:47 +02:00
|
|
|
this->modeButton_->hide();
|
2018-07-04 13:05:54 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-07-15 20:28:54 +02:00
|
|
|
auto roomModes = twitchChannel->accessRoomModes();
|
2018-07-04 13:05:54 +02:00
|
|
|
|
2018-07-15 20:28:54 +02:00
|
|
|
setR9k->setChecked(roomModes->r9k);
|
|
|
|
setSlow->setChecked(roomModes->slowMode);
|
|
|
|
setEmote->setChecked(roomModes->emoteOnly);
|
|
|
|
setSub->setChecked(roomModes->submode);
|
2019-08-25 19:08:04 +02:00
|
|
|
setFollowers->setChecked(roomModes->followerOnly != -1);
|
2018-07-04 19:43:41 +02:00
|
|
|
}));
|
2018-07-04 13:05:54 +02:00
|
|
|
|
2018-08-08 15:35:54 +02:00
|
|
|
auto toggle = [this](const QString &command, QAction *action) mutable {
|
|
|
|
this->split_->getChannel().get()->sendMessage(
|
|
|
|
command + (action->isChecked() ? "" : "off"));
|
2018-07-04 19:43:41 +02:00
|
|
|
action->setChecked(!action->isChecked());
|
|
|
|
};
|
2018-06-24 12:22:50 +02:00
|
|
|
|
2020-11-08 12:02:19 +01:00
|
|
|
QObject::connect(setSub, &QAction::triggered, this,
|
|
|
|
[setSub, toggle]() mutable {
|
|
|
|
toggle("/subscribers", setSub);
|
|
|
|
});
|
2018-06-24 12:22:50 +02:00
|
|
|
|
2020-11-08 12:02:19 +01:00
|
|
|
QObject::connect(setEmote, &QAction::triggered, this,
|
|
|
|
[setEmote, toggle]() mutable {
|
|
|
|
toggle("/emoteonly", setEmote);
|
|
|
|
});
|
2018-06-24 12:22:50 +02:00
|
|
|
|
|
|
|
QObject::connect(setSlow, &QAction::triggered, this, [setSlow, this]() {
|
2018-10-21 13:43:02 +02:00
|
|
|
if (!setSlow->isChecked())
|
|
|
|
{
|
2018-07-06 19:23:47 +02:00
|
|
|
this->split_->getChannel().get()->sendMessage("/slowoff");
|
2018-06-24 12:22:50 +02:00
|
|
|
setSlow->setChecked(false);
|
|
|
|
return;
|
|
|
|
};
|
2018-08-08 15:35:54 +02:00
|
|
|
auto ok = bool();
|
|
|
|
auto seconds = QInputDialog::getInt(this, "", "Seconds:", 10, 0, 500, 1,
|
|
|
|
&ok, Qt::FramelessWindowHint);
|
2018-10-21 13:43:02 +02:00
|
|
|
if (ok)
|
|
|
|
{
|
2018-08-06 21:17:03 +02:00
|
|
|
this->split_->getChannel().get()->sendMessage(
|
2018-08-08 15:35:54 +02:00
|
|
|
QString("/slow %1").arg(seconds));
|
2018-10-21 13:43:02 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-06-26 20:36:33 +02:00
|
|
|
setSlow->setChecked(false);
|
2018-06-24 12:22:50 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2019-08-25 19:08:04 +02:00
|
|
|
QObject::connect(
|
|
|
|
setFollowers, &QAction::triggered, this, [setFollowers, this]() {
|
|
|
|
if (!setFollowers->isChecked())
|
|
|
|
{
|
|
|
|
this->split_->getChannel().get()->sendMessage("/followersoff");
|
|
|
|
setFollowers->setChecked(false);
|
|
|
|
return;
|
|
|
|
};
|
|
|
|
auto ok = bool();
|
|
|
|
auto time = QInputDialog::getText(
|
|
|
|
this, "", "Time:", QLineEdit::Normal, "15m", &ok,
|
|
|
|
Qt::FramelessWindowHint,
|
|
|
|
Qt::ImhLowercaseOnly | Qt::ImhPreferNumbers);
|
|
|
|
if (ok)
|
|
|
|
{
|
|
|
|
this->split_->getChannel().get()->sendMessage(
|
|
|
|
QString("/followers %1").arg(time));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
setFollowers->setChecked(false);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-11-08 12:02:19 +01:00
|
|
|
QObject::connect(setR9k, &QAction::triggered, this,
|
|
|
|
[setR9k, toggle]() mutable {
|
|
|
|
toggle("/r9kbeta", setR9k);
|
|
|
|
});
|
2018-08-07 23:46:00 +02:00
|
|
|
|
|
|
|
return menu;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SplitHeader::updateRoomModes()
|
|
|
|
{
|
|
|
|
this->modeUpdateRequested_.invoke();
|
|
|
|
}
|
|
|
|
|
2018-08-08 15:35:54 +02:00
|
|
|
void SplitHeader::initializeModeSignals(EffectLabel &label)
|
2018-08-07 23:46:00 +02:00
|
|
|
{
|
2018-08-08 15:35:54 +02:00
|
|
|
this->modeUpdateRequested_.connect([this, &label] {
|
2020-11-08 12:02:19 +01:00
|
|
|
if (auto twitchChannel =
|
|
|
|
dynamic_cast<TwitchChannel *>(this->split_->getChannel().get()))
|
2018-08-08 15:50:43 +02:00
|
|
|
{
|
2018-08-07 23:46:00 +02:00
|
|
|
label.setEnable(twitchChannel->hasModRights());
|
|
|
|
|
|
|
|
// set the label text
|
2018-08-08 15:50:43 +02:00
|
|
|
auto text = formatRoomMode(*twitchChannel);
|
2018-08-07 23:46:00 +02:00
|
|
|
|
2018-10-21 13:43:02 +02:00
|
|
|
if (!text.isEmpty())
|
|
|
|
{
|
2018-08-07 23:46:00 +02:00
|
|
|
label.getLabel().setText(text);
|
|
|
|
label.show();
|
2018-08-08 15:50:43 +02:00
|
|
|
return;
|
2018-08-07 23:46:00 +02:00
|
|
|
}
|
2018-08-08 15:35:54 +02:00
|
|
|
}
|
2018-08-08 15:50:43 +02:00
|
|
|
|
|
|
|
label.hide();
|
2018-08-08 15:35:54 +02:00
|
|
|
});
|
2018-06-24 12:22:50 +02:00
|
|
|
}
|
|
|
|
|
2020-10-18 12:19:30 +02:00
|
|
|
void SplitHeader::resetThumbnail()
|
|
|
|
{
|
|
|
|
this->lastThumbnail_.invalidate();
|
|
|
|
this->thumbnail_.clear();
|
|
|
|
}
|
|
|
|
|
2018-08-08 15:35:54 +02:00
|
|
|
void SplitHeader::handleChannelChanged()
|
2017-11-04 14:57:29 +01:00
|
|
|
{
|
2020-10-18 12:19:30 +02:00
|
|
|
this->resetThumbnail();
|
|
|
|
|
|
|
|
this->updateChannelText();
|
|
|
|
|
2018-08-08 15:35:54 +02:00
|
|
|
this->channelConnections_.clear();
|
2017-11-04 14:57:29 +01:00
|
|
|
|
2018-07-06 19:23:47 +02:00
|
|
|
auto channel = this->split_->getChannel();
|
2018-10-21 13:43:02 +02:00
|
|
|
if (auto twitchChannel = dynamic_cast<TwitchChannel *>(channel.get()))
|
|
|
|
{
|
2018-08-08 15:35:54 +02:00
|
|
|
this->channelConnections_.emplace_back(
|
2020-10-18 12:19:30 +02:00
|
|
|
twitchChannel->liveStatusChanged.connect([this]() {
|
2020-11-08 12:02:19 +01:00
|
|
|
this->updateChannelText();
|
2020-10-18 12:19:30 +02:00
|
|
|
}));
|
2017-11-04 14:57:29 +01:00
|
|
|
}
|
2017-01-15 16:38:30 +01:00
|
|
|
}
|
|
|
|
|
2018-01-25 21:11:14 +01:00
|
|
|
void SplitHeader::scaleChangedEvent(float scale)
|
2017-09-22 00:50:43 +02:00
|
|
|
{
|
2018-07-04 19:43:41 +02:00
|
|
|
int w = int(28 * scale);
|
2018-01-13 04:05:38 +01:00
|
|
|
|
|
|
|
this->setFixedHeight(w);
|
2018-07-06 19:23:47 +02:00
|
|
|
this->dropdownButton_->setFixedWidth(w);
|
|
|
|
this->moderationButton_->setFixedWidth(w);
|
2020-10-10 17:24:53 +02:00
|
|
|
this->viewersButton_->setFixedWidth(w);
|
2018-09-04 21:39:54 +02:00
|
|
|
this->addButton_->setFixedWidth(w * 5 / 8);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SplitHeader::setAddButtonVisible(bool value)
|
|
|
|
{
|
|
|
|
this->addButton_->setVisible(value);
|
2017-09-22 00:50:43 +02:00
|
|
|
}
|
|
|
|
|
2020-10-10 17:24:53 +02:00
|
|
|
void SplitHeader::setViewersButtonVisible(bool value)
|
|
|
|
{
|
|
|
|
this->viewersButton_->setVisible(value);
|
|
|
|
}
|
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
void SplitHeader::updateChannelText()
|
2017-01-17 00:15:44 +01:00
|
|
|
{
|
2018-07-06 19:23:47 +02:00
|
|
|
auto indirectChannel = this->split_->getIndirectChannel();
|
|
|
|
auto channel = this->split_->getChannel();
|
2018-08-08 15:35:54 +02:00
|
|
|
this->isLive_ = false;
|
|
|
|
this->tooltipText_ = QString();
|
2018-04-20 19:54:45 +02:00
|
|
|
|
2020-12-06 14:07:33 +01:00
|
|
|
auto title = channel->getLocalizedName();
|
2018-04-20 22:33:28 +02:00
|
|
|
|
2018-08-08 15:35:54 +02:00
|
|
|
if (indirectChannel.getType() == Channel::Type::TwitchWatching)
|
2018-04-20 22:33:28 +02:00
|
|
|
title = "watching: " + (title.isEmpty() ? "none" : title);
|
2018-03-30 15:05:33 +02:00
|
|
|
|
2018-10-21 13:43:02 +02:00
|
|
|
if (auto twitchChannel = dynamic_cast<TwitchChannel *>(channel.get()))
|
|
|
|
{
|
2018-07-15 20:28:54 +02:00
|
|
|
const auto streamStatus = twitchChannel->accessStreamStatus();
|
2018-03-30 15:05:33 +02:00
|
|
|
|
2018-10-21 13:43:02 +02:00
|
|
|
if (streamStatus->live)
|
|
|
|
{
|
2018-07-06 19:23:47 +02:00
|
|
|
this->isLive_ = true;
|
2020-09-26 09:30:50 +02:00
|
|
|
// XXX: This URL format can be figured out from the Helix Get Streams API which we parse in TwitchChannel::parseLiveStatus
|
2020-05-24 11:57:15 +02:00
|
|
|
QString url = "https://static-cdn.jtvnw.net/"
|
|
|
|
"previews-ttv/live_user_" +
|
|
|
|
channel->getName().toLower();
|
|
|
|
switch (getSettings()->thumbnailSizeStream.getValue())
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
url.append("-80x45.jpg");
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
url.append("-160x90.jpg");
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
url.append("-360x180.jpg");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
url = "";
|
|
|
|
}
|
|
|
|
if (!url.isEmpty() &&
|
|
|
|
(!this->lastThumbnail_.isValid() ||
|
|
|
|
this->lastThumbnail_.elapsed() > 5 * 60 * 1000))
|
|
|
|
{
|
|
|
|
NetworkRequest(url, NetworkRequestType::Get)
|
|
|
|
.onSuccess([this](auto result) -> Outcome {
|
2020-09-26 09:30:50 +02:00
|
|
|
// NOTE: We do not follow the redirects, so we need to make sure we only treat code 200 as a valid image
|
|
|
|
if (result.status() == 200)
|
|
|
|
{
|
|
|
|
this->thumbnail_ = QString::fromLatin1(
|
|
|
|
result.getData().toBase64());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this->thumbnail_.clear();
|
|
|
|
}
|
|
|
|
this->updateChannelText();
|
2020-05-24 11:57:15 +02:00
|
|
|
return Success;
|
|
|
|
})
|
|
|
|
.execute();
|
|
|
|
this->lastThumbnail_.restart();
|
|
|
|
}
|
|
|
|
this->tooltipText_ = formatTooltip(*streamStatus, this->thumbnail_);
|
2018-08-08 15:35:54 +02:00
|
|
|
title += formatTitle(*streamStatus, *getSettings());
|
2017-09-11 22:37:39 +02:00
|
|
|
}
|
2019-10-12 15:09:12 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
this->tooltipText_ = formatOfflineTooltip(*streamStatus);
|
|
|
|
}
|
2017-07-09 17:49:02 +02:00
|
|
|
}
|
2018-03-30 15:05:33 +02:00
|
|
|
|
2020-10-18 15:16:56 +02:00
|
|
|
if (!title.isEmpty() && this->split_->getFilters().size() != 0)
|
|
|
|
{
|
|
|
|
title += " - filtered";
|
|
|
|
}
|
|
|
|
|
2018-09-04 21:39:54 +02:00
|
|
|
this->titleLabel_->setText(title.isEmpty() ? "<empty>" : title);
|
2017-01-17 00:15:44 +01:00
|
|
|
}
|
|
|
|
|
2018-01-17 16:52:51 +01:00
|
|
|
void SplitHeader::updateModerationModeIcon()
|
|
|
|
{
|
2019-08-11 21:08:18 +02:00
|
|
|
auto moderationMode = this->split_->getModerationMode() &&
|
2020-02-23 23:07:28 +01:00
|
|
|
!getSettings()->moderationActions.empty();
|
2018-10-21 16:13:26 +02:00
|
|
|
|
2018-08-06 21:17:03 +02:00
|
|
|
this->moderationButton_->setPixmap(
|
2019-09-22 10:53:39 +02:00
|
|
|
moderationMode ? getResources().buttons.modModeEnabled
|
|
|
|
: getResources().buttons.modModeDisabled);
|
2018-01-17 18:36:12 +01:00
|
|
|
|
2018-08-08 15:35:54 +02:00
|
|
|
auto channel = this->split_->getChannel();
|
2018-08-07 23:46:00 +02:00
|
|
|
auto twitchChannel = dynamic_cast<TwitchChannel *>(channel.get());
|
2018-01-17 18:36:12 +01:00
|
|
|
|
2020-01-26 10:10:40 +01:00
|
|
|
if (twitchChannel != nullptr &&
|
|
|
|
(twitchChannel->hasModRights() || moderationMode))
|
|
|
|
{
|
2018-08-08 15:35:54 +02:00
|
|
|
this->moderationButton_->show();
|
2020-01-26 10:10:40 +01:00
|
|
|
}
|
2018-08-08 15:35:54 +02:00
|
|
|
else
|
2020-01-26 10:10:40 +01:00
|
|
|
{
|
2018-08-08 15:35:54 +02:00
|
|
|
this->moderationButton_->hide();
|
2020-01-26 10:10:40 +01:00
|
|
|
}
|
2018-01-17 16:52:51 +01:00
|
|
|
}
|
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
void SplitHeader::paintEvent(QPaintEvent *)
|
2017-01-01 02:30:42 +01:00
|
|
|
{
|
|
|
|
QPainter painter(this);
|
|
|
|
|
2018-07-06 17:11:37 +02:00
|
|
|
painter.fillRect(rect(), this->theme->splits.header.background);
|
|
|
|
painter.setPen(this->theme->splits.header.border);
|
2018-11-01 18:04:14 +01:00
|
|
|
painter.drawRect(0, 0, width() - 1, height() - 2);
|
|
|
|
painter.fillRect(0, height() - 1, width(), 1,
|
|
|
|
this->theme->splits.background);
|
2017-01-01 02:30:42 +01:00
|
|
|
}
|
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
void SplitHeader::mousePressEvent(QMouseEvent *event)
|
2017-01-01 02:30:42 +01:00
|
|
|
{
|
2019-07-13 12:17:22 +02:00
|
|
|
switch (event->button())
|
2018-10-21 13:43:02 +02:00
|
|
|
{
|
2019-09-26 00:51:05 +02:00
|
|
|
case Qt::LeftButton: {
|
2021-05-01 16:14:05 +02:00
|
|
|
this->split_->giveFocus(Qt::MouseFocusReason);
|
|
|
|
|
2019-07-13 12:17:22 +02:00
|
|
|
this->dragging_ = true;
|
|
|
|
|
|
|
|
this->dragStart_ = event->pos();
|
|
|
|
}
|
|
|
|
break;
|
2018-05-16 14:55:45 +02:00
|
|
|
|
2019-09-26 00:51:05 +02:00
|
|
|
case Qt::RightButton: {
|
2019-10-12 11:17:40 +02:00
|
|
|
auto menu = this->createMainMenu().release();
|
|
|
|
menu->setAttribute(Qt::WA_DeleteOnClose);
|
|
|
|
menu->popup(this->mapToGlobal(event->pos() + QPoint(0, 4)));
|
2019-07-13 12:17:22 +02:00
|
|
|
}
|
|
|
|
break;
|
2018-05-16 14:55:45 +02:00
|
|
|
}
|
2017-01-01 02:30:42 +01:00
|
|
|
|
2018-07-06 19:23:47 +02:00
|
|
|
this->doubleClicked_ = false;
|
2018-05-16 14:55:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void SplitHeader::mouseReleaseEvent(QMouseEvent *event)
|
|
|
|
{
|
2018-07-06 19:23:47 +02:00
|
|
|
this->dragging_ = false;
|
2017-01-01 02:30:42 +01:00
|
|
|
}
|
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
void SplitHeader::mouseMoveEvent(QMouseEvent *event)
|
2017-01-01 02:30:42 +01:00
|
|
|
{
|
2018-10-21 13:43:02 +02:00
|
|
|
if (this->dragging_)
|
|
|
|
{
|
2018-11-21 21:37:41 +01:00
|
|
|
if (distance(this->dragStart_, event->pos()) > 15 * this->scale())
|
2018-10-21 13:43:02 +02:00
|
|
|
{
|
2018-07-06 19:23:47 +02:00
|
|
|
this->split_->drag();
|
|
|
|
this->dragging_ = false;
|
2018-05-11 13:55:10 +02:00
|
|
|
}
|
|
|
|
}
|
2017-01-01 02:30:42 +01:00
|
|
|
}
|
|
|
|
|
2017-11-12 17:21:50 +01:00
|
|
|
void SplitHeader::mouseDoubleClickEvent(QMouseEvent *event)
|
2017-01-17 00:15:44 +01:00
|
|
|
{
|
2018-10-21 13:43:02 +02:00
|
|
|
if (event->button() == Qt::LeftButton)
|
|
|
|
{
|
2018-08-08 15:35:54 +02:00
|
|
|
this->split_->changeChannel();
|
2017-01-17 00:15:44 +01:00
|
|
|
}
|
2018-07-06 19:23:47 +02:00
|
|
|
this->doubleClicked_ = true;
|
2017-01-17 00:15:44 +01:00
|
|
|
}
|
|
|
|
|
2018-05-26 16:31:43 +02:00
|
|
|
void SplitHeader::enterEvent(QEvent *event)
|
|
|
|
{
|
2018-10-21 13:43:02 +02:00
|
|
|
if (!this->tooltipText_.isEmpty())
|
|
|
|
{
|
2019-10-12 15:09:12 +02:00
|
|
|
auto channel = this->split_->getChannel().get();
|
|
|
|
if (channel->getType() == Channel::Type::Twitch)
|
|
|
|
{
|
|
|
|
dynamic_cast<TwitchChannel *>(channel)->refreshTitle();
|
|
|
|
}
|
|
|
|
|
2019-10-07 22:42:34 +02:00
|
|
|
TooltipPreviewImage::instance().setImage(nullptr);
|
2019-06-22 16:39:59 +02:00
|
|
|
|
2019-10-07 22:42:34 +02:00
|
|
|
auto tooltip = TooltipWidget::instance();
|
2018-08-08 15:35:54 +02:00
|
|
|
tooltip->setText(this->tooltipText_);
|
2020-08-22 11:54:06 +02:00
|
|
|
tooltip->setWordWrap(true);
|
2018-08-24 11:56:42 +02:00
|
|
|
tooltip->adjustSize();
|
2020-08-13 20:59:57 +02:00
|
|
|
auto pos = this->mapToGlobal(this->rect().bottomLeft()) +
|
2020-09-25 22:21:30 +02:00
|
|
|
QPoint((this->width() - tooltip->width()) / 2, 1);
|
2020-08-13 19:00:56 +02:00
|
|
|
|
|
|
|
tooltip->moveTo(this, pos, false);
|
2018-08-08 15:35:54 +02:00
|
|
|
tooltip->show();
|
|
|
|
tooltip->raise();
|
2018-05-26 16:31:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
BaseWidget::enterEvent(event);
|
|
|
|
}
|
|
|
|
|
2018-05-16 14:55:45 +02:00
|
|
|
void SplitHeader::leaveEvent(QEvent *event)
|
|
|
|
{
|
2019-10-07 22:42:34 +02:00
|
|
|
TooltipWidget::instance()->hide();
|
2018-05-26 16:31:43 +02:00
|
|
|
|
2018-05-16 14:55:45 +02:00
|
|
|
BaseWidget::leaveEvent(event);
|
|
|
|
}
|
2018-05-26 16:31:43 +02:00
|
|
|
|
2018-07-06 17:11:37 +02:00
|
|
|
void SplitHeader::themeChangedEvent()
|
2017-07-02 14:28:37 +02:00
|
|
|
{
|
2018-08-08 15:35:54 +02:00
|
|
|
auto palette = QPalette();
|
2018-06-23 13:54:00 +02:00
|
|
|
|
2018-10-21 13:43:02 +02:00
|
|
|
if (this->split_->hasFocus())
|
|
|
|
{
|
2021-03-13 16:03:16 +01:00
|
|
|
palette.setColor(QPalette::WindowText,
|
2018-08-06 21:17:03 +02:00
|
|
|
this->theme->splits.header.focusedText);
|
2018-10-21 13:43:02 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-03-13 16:03:16 +01:00
|
|
|
palette.setColor(QPalette::WindowText, this->theme->splits.header.text);
|
2018-06-23 13:54:00 +02:00
|
|
|
}
|
2018-09-04 21:39:54 +02:00
|
|
|
this->titleLabel_->setPalette(palette);
|
2017-07-02 14:28:37 +02:00
|
|
|
|
2018-08-08 15:35:54 +02:00
|
|
|
// --
|
2018-10-21 13:43:02 +02:00
|
|
|
if (this->theme->isLightTheme())
|
|
|
|
{
|
2020-10-10 17:24:53 +02:00
|
|
|
this->viewersButton_->setPixmap(getResources().buttons.viewersDark);
|
2019-09-22 10:53:39 +02:00
|
|
|
this->dropdownButton_->setPixmap(getResources().buttons.menuDark);
|
|
|
|
this->addButton_->setPixmap(getResources().buttons.addSplit);
|
2018-10-21 13:43:02 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-10-10 17:24:53 +02:00
|
|
|
this->viewersButton_->setPixmap(getResources().buttons.viewersLight);
|
2019-09-26 00:51:05 +02:00
|
|
|
this->dropdownButton_->setPixmap(getResources().buttons.menuLight);
|
2019-09-22 10:53:39 +02:00
|
|
|
this->addButton_->setPixmap(getResources().buttons.addSplitDark);
|
2018-07-04 14:13:29 +02:00
|
|
|
}
|
2017-07-02 14:28:37 +02:00
|
|
|
}
|
|
|
|
|
2018-08-08 15:35:54 +02:00
|
|
|
void SplitHeader::reloadChannelEmotes()
|
2017-01-15 16:38:30 +01:00
|
|
|
{
|
2018-07-06 19:23:47 +02:00
|
|
|
auto channel = this->split_->getChannel();
|
2018-06-05 15:03:34 +02:00
|
|
|
|
2018-08-08 15:35:54 +02:00
|
|
|
if (auto twitchChannel = dynamic_cast<TwitchChannel *>(channel.get()))
|
2019-08-27 20:45:55 +02:00
|
|
|
{
|
2020-05-16 12:43:44 +02:00
|
|
|
twitchChannel->refreshFFZChannelEmotes(true);
|
|
|
|
twitchChannel->refreshBTTVChannelEmotes(true);
|
2019-08-27 20:45:55 +02:00
|
|
|
}
|
2017-01-15 16:38:30 +01:00
|
|
|
}
|
2017-06-10 23:53:39 +02:00
|
|
|
|
2018-10-04 22:34:57 +02:00
|
|
|
void SplitHeader::reloadSubscriberEmotes()
|
|
|
|
{
|
2021-08-08 12:59:28 +02:00
|
|
|
auto channel = this->split_->getChannel();
|
|
|
|
getApp()->accounts->twitch.getCurrent()->loadEmotes(channel);
|
2018-10-04 22:34:57 +02:00
|
|
|
}
|
|
|
|
|
2018-08-08 15:35:54 +02:00
|
|
|
void SplitHeader::reconnect()
|
2017-01-15 16:38:30 +01:00
|
|
|
{
|
2019-09-18 08:05:51 +02:00
|
|
|
this->split_->getChannel()->reconnect();
|
2017-01-15 16:38:30 +01:00
|
|
|
}
|
2017-06-07 10:09:24 +02:00
|
|
|
|
|
|
|
} // namespace chatterino
|