mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
/live split for channels going live (#1998)
Co-authored-by: 23rd <23rd@vivaldi.net> Co-authored-by: Rasmus Karlsson <rasmus.karlsson@pajlada.com>
This commit is contained in:
parent
d96f4575ba
commit
dcd65b5978
|
@ -2,12 +2,14 @@
|
|||
|
||||
## Unversioned
|
||||
|
||||
- Major: New split for channels going live! /live. (#1797)
|
||||
- Minor: Hosting messages are now clickable. (#2655)
|
||||
- Minor: Messages held by automod are now shown to the user. (#2626)
|
||||
- Bugfix: Strip newlines from stream titles to prevent text going off of split header (#2755)
|
||||
- Bugfix: Automod messages now work properly again. (#2682)
|
||||
- Bugfix: `Login expired` message no longer highlights all tabs. (#2735)
|
||||
- Bugfix: Fix a deadlock that would occur during user badge loading. (#1704, #2756)
|
||||
- Bugfix: Tabbing in `Select a channel to open` is now consistent. (#1797)
|
||||
|
||||
## 2.3.1
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ public:
|
|||
TwitchWhispers,
|
||||
TwitchWatching,
|
||||
TwitchMentions,
|
||||
TwitchLive,
|
||||
TwitchEnd,
|
||||
Irc,
|
||||
Misc
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "common/QLogging.hpp"
|
||||
#include "controllers/notifications/NotificationModel.hpp"
|
||||
#include "providers/twitch/TwitchIrcServer.hpp"
|
||||
#include "providers/twitch/TwitchMessageBuilder.hpp"
|
||||
#include "providers/twitch/api/Helix.hpp"
|
||||
#include "singletons/Toasts.hpp"
|
||||
#include "singletons/WindowManager.hpp"
|
||||
|
@ -185,6 +186,9 @@ void NotificationController::getFakeTwitchChannelLiveStatus(
|
|||
{
|
||||
getApp()->windows->sendAlert();
|
||||
}
|
||||
MessageBuilder builder;
|
||||
TwitchMessageBuilder::liveMessage(channelName, &builder);
|
||||
getApp()->twitch2->liveChannel->addMessage(builder.release());
|
||||
|
||||
// Indicate that we have pushed notifications for this stream
|
||||
fakeTwitchChannels.push_back(channelName);
|
||||
|
|
|
@ -563,10 +563,25 @@ void TwitchChannel::setLive(bool newLiveStatus)
|
|||
getApp()->windows->sendAlert();
|
||||
}
|
||||
}
|
||||
// Channel live message
|
||||
MessageBuilder builder;
|
||||
TwitchMessageBuilder::liveSystemMessage(this->getDisplayName(),
|
||||
&builder);
|
||||
this->addMessage(builder.release());
|
||||
|
||||
// Message in /live channel
|
||||
MessageBuilder builder2;
|
||||
TwitchMessageBuilder::liveMessage(this->getDisplayName(),
|
||||
&builder2);
|
||||
getApp()->twitch2->liveChannel->addMessage(builder2.release());
|
||||
|
||||
// Notify on all channels with a ping sound
|
||||
if (getSettings()->notificationOnAnyChannel &&
|
||||
!(isInStreamerMode() &&
|
||||
getSettings()->streamerModeSuppressLiveNotifications))
|
||||
{
|
||||
getApp()->notifications->playSound();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -28,6 +28,7 @@ TwitchIrcServer::TwitchIrcServer()
|
|||
: whispersChannel(new Channel("/whispers", Channel::Type::TwitchWhispers))
|
||||
, mentionsChannel(new Channel("/mentions", Channel::Type::TwitchMentions))
|
||||
, watchingChannel(Channel::getEmpty(), Channel::Type::TwitchWatching)
|
||||
, liveChannel(new Channel("/live", Channel::Type::TwitchLive))
|
||||
{
|
||||
this->initializeIrc();
|
||||
|
||||
|
@ -257,6 +258,11 @@ std::shared_ptr<Channel> TwitchIrcServer::getCustomChannel(
|
|||
return this->mentionsChannel;
|
||||
}
|
||||
|
||||
if (channelName == "/live")
|
||||
{
|
||||
return this->liveChannel;
|
||||
}
|
||||
|
||||
if (channelName == "$$$")
|
||||
{
|
||||
static auto channel =
|
||||
|
@ -289,6 +295,7 @@ void TwitchIrcServer::forEachChannelAndSpecialChannels(
|
|||
|
||||
func(this->whispersChannel);
|
||||
func(this->mentionsChannel);
|
||||
func(this->liveChannel);
|
||||
}
|
||||
|
||||
std::shared_ptr<Channel> TwitchIrcServer::getChannelOrEmptyByID(
|
||||
|
|
|
@ -35,6 +35,7 @@ public:
|
|||
|
||||
const ChannelPtr whispersChannel;
|
||||
const ChannelPtr mentionsChannel;
|
||||
const ChannelPtr liveChannel;
|
||||
IndirectChannel watchingChannel;
|
||||
|
||||
PubSub *pubsub;
|
||||
|
|
|
@ -1302,6 +1302,18 @@ void TwitchMessageBuilder::appendChannelPointRewardMessage(
|
|||
builder->message().flags.set(MessageFlag::RedeemedChannelPointReward);
|
||||
}
|
||||
|
||||
void TwitchMessageBuilder::liveMessage(const QString &channelName,
|
||||
MessageBuilder *builder)
|
||||
{
|
||||
builder->emplace<TimestampElement>();
|
||||
builder
|
||||
->emplace<TextElement>(channelName, MessageElementFlag::Username,
|
||||
MessageColor::Text, FontStyle::ChatMediumBold)
|
||||
->setLink({Link::UserInfo, channelName});
|
||||
builder->emplace<TextElement>("is live!", MessageElementFlag::Text,
|
||||
MessageColor::Text);
|
||||
}
|
||||
|
||||
void TwitchMessageBuilder::liveSystemMessage(const QString &channelName,
|
||||
MessageBuilder *builder)
|
||||
{
|
||||
|
|
|
@ -52,6 +52,12 @@ public:
|
|||
|
||||
static void appendChannelPointRewardMessage(
|
||||
const ChannelPointReward &reward, MessageBuilder *builder);
|
||||
|
||||
// Message in the /live chat for channel going live
|
||||
static void liveMessage(const QString &channelName,
|
||||
MessageBuilder *builder);
|
||||
|
||||
// Messages in normal chat for channel stuff
|
||||
static void liveSystemMessage(const QString &channelName,
|
||||
MessageBuilder *builder);
|
||||
static void offlineSystemMessage(const QString &channelName,
|
||||
|
|
|
@ -300,6 +300,8 @@ public:
|
|||
false};
|
||||
QStringSetting notificationPathSound = {"/notifications/highlightSoundPath",
|
||||
"qrc:/sounds/ping3.wav"};
|
||||
BoolSetting notificationOnAnyChannel = {"/notifications/onAnyChannel",
|
||||
false};
|
||||
|
||||
BoolSetting notificationToast = {"/notifications/enableToast", false};
|
||||
IntSetting openFromToast = {"/notifications/openFromToast",
|
||||
|
|
|
@ -559,6 +559,10 @@ void WindowManager::encodeChannel(IndirectChannel channel, QJsonObject &obj)
|
|||
obj.insert("type", "whispers");
|
||||
}
|
||||
break;
|
||||
case Channel::Type::TwitchLive: {
|
||||
obj.insert("type", "live");
|
||||
}
|
||||
break;
|
||||
case Channel::Type::Irc: {
|
||||
if (auto ircChannel =
|
||||
dynamic_cast<IrcChannel *>(channel.get().get()))
|
||||
|
@ -608,6 +612,10 @@ IndirectChannel WindowManager::decodeChannel(const SplitDescriptor &descriptor)
|
|||
{
|
||||
return app->twitch.server->whispersChannel;
|
||||
}
|
||||
else if (descriptor.type_ == "live")
|
||||
{
|
||||
return app->twitch.server->liveChannel;
|
||||
}
|
||||
else if (descriptor.type_ == "irc")
|
||||
{
|
||||
return Irc::instance().getOrAddChannel(descriptor.server_,
|
||||
|
|
|
@ -119,17 +119,31 @@ SelectChannelDialog::SelectChannelDialog(QWidget *parent)
|
|||
watching_lbl->setVisible(enabled);
|
||||
});
|
||||
|
||||
// live_btn
|
||||
auto live_btn =
|
||||
vbox.emplace<QRadioButton>("Live").assign(&this->ui_.twitch.live);
|
||||
auto live_lbl =
|
||||
vbox.emplace<QLabel>("Shows when channels go live.").hidden();
|
||||
|
||||
live_lbl->setWordWrap(true);
|
||||
live_btn->installEventFilter(&this->tabFilter_);
|
||||
|
||||
QObject::connect(live_btn.getElement(), &QRadioButton::toggled,
|
||||
[=](bool enabled) mutable {
|
||||
live_lbl->setVisible(enabled);
|
||||
});
|
||||
|
||||
vbox->addStretch(1);
|
||||
|
||||
// tabbing order
|
||||
QWidget::setTabOrder(watching_btn.getElement(),
|
||||
channel_btn.getElement());
|
||||
QWidget::setTabOrder(live_btn.getElement(), channel_btn.getElement());
|
||||
QWidget::setTabOrder(channel_btn.getElement(),
|
||||
whispers_btn.getElement());
|
||||
QWidget::setTabOrder(whispers_btn.getElement(),
|
||||
mentions_btn.getElement());
|
||||
QWidget::setTabOrder(mentions_btn.getElement(),
|
||||
watching_btn.getElement());
|
||||
QWidget::setTabOrder(watching_btn.getElement(), live_btn.getElement());
|
||||
|
||||
// tab
|
||||
auto tab = notebook->addPage(obj.getElement());
|
||||
|
@ -294,6 +308,11 @@ void SelectChannelDialog::setSelectedChannel(IndirectChannel _channel)
|
|||
this->ui_.twitch.whispers->setFocus();
|
||||
}
|
||||
break;
|
||||
case Channel::Type::TwitchLive: {
|
||||
this->ui_.notebook->selectIndex(TAB_TWITCH);
|
||||
this->ui_.twitch.live->setFocus();
|
||||
}
|
||||
break;
|
||||
case Channel::Type::Irc: {
|
||||
this->ui_.notebook->selectIndex(TAB_IRC);
|
||||
this->ui_.irc.channel->setText(_channel.get()->getName());
|
||||
|
@ -357,6 +376,10 @@ IndirectChannel SelectChannelDialog::getSelectedChannel() const
|
|||
{
|
||||
return app->twitch.server->whispersChannel;
|
||||
}
|
||||
else if (this->ui_.twitch.live->isChecked())
|
||||
{
|
||||
return app->twitch.server->liveChannel;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TAB_IRC: {
|
||||
|
@ -417,15 +440,22 @@ bool SelectChannelDialog::EventFilter::eventFilter(QObject *watched,
|
|||
event_key->key() == Qt::Key_Down) &&
|
||||
event_key->modifiers() == Qt::NoModifier)
|
||||
{
|
||||
// Tab has been pressed, focus next entry in list
|
||||
|
||||
if (widget == this->dialog->ui_.twitch.channelName)
|
||||
{
|
||||
// Special case for when current selection is the "Channel" entry's edit box since the Edit box actually has the focus
|
||||
this->dialog->ui_.twitch.whispers->setFocus();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
else if (widget == this->dialog->ui_.twitch.live)
|
||||
{
|
||||
widget->nextInFocusChain()->setFocus();
|
||||
// Special case for when current selection is "Live" (the last entry in the list), next wrap is Channel, but we need to select its edit box
|
||||
this->dialog->ui_.twitch.channel->setFocus();
|
||||
return true;
|
||||
}
|
||||
|
||||
widget->nextInFocusChain()->setFocus();
|
||||
return true;
|
||||
}
|
||||
else if (((event_key->key() == Qt::Key_Tab ||
|
||||
|
@ -434,14 +464,12 @@ bool SelectChannelDialog::EventFilter::eventFilter(QObject *watched,
|
|||
((event_key->key() == Qt::Key_Up) &&
|
||||
event_key->modifiers() == Qt::NoModifier))
|
||||
{
|
||||
// Shift+Tab has been pressed, focus previous entry in list
|
||||
|
||||
if (widget == this->dialog->ui_.twitch.channelName)
|
||||
{
|
||||
this->dialog->ui_.twitch.watching->setFocus();
|
||||
return true;
|
||||
}
|
||||
else if (widget == this->dialog->ui_.twitch.whispers)
|
||||
{
|
||||
this->dialog->ui_.twitch.channel->setFocus();
|
||||
// Special case for when current selection is the "Channel" entry's edit box since the Edit box actually has the focus
|
||||
this->dialog->ui_.twitch.live->setFocus();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ private:
|
|||
QRadioButton *whispers;
|
||||
QRadioButton *mentions;
|
||||
QRadioButton *watching;
|
||||
QRadioButton *live;
|
||||
} twitch;
|
||||
struct {
|
||||
QLineEdit *channel;
|
||||
|
|
|
@ -994,7 +994,8 @@ MessageElementFlags ChannelView::getFlags() const
|
|||
{
|
||||
flags.set(MessageElementFlag::ModeratorTools);
|
||||
}
|
||||
if (this->underlyingChannel_ == app->twitch.server->mentionsChannel)
|
||||
if (this->underlyingChannel_ == app->twitch.server->mentionsChannel ||
|
||||
this->underlyingChannel_ == app->twitch.server->liveChannel)
|
||||
{
|
||||
flags.set(MessageElementFlag::ChannelName);
|
||||
flags.unset(MessageElementFlag::ChannelPointReward);
|
||||
|
|
|
@ -35,8 +35,12 @@ NotificationPage::NotificationPage()
|
|||
|
||||
settings.append(this->createCheckBox(
|
||||
"Flash taskbar", getSettings()->notificationFlashTaskbar));
|
||||
settings.append(
|
||||
this->createCheckBox("Play sound for selected channels",
|
||||
getSettings()->notificationPlaySound));
|
||||
settings.append(this->createCheckBox(
|
||||
"Play sound", getSettings()->notificationPlaySound));
|
||||
"Play sound for any channel going live",
|
||||
getSettings()->notificationOnAnyChannel));
|
||||
#ifdef Q_OS_WIN
|
||||
settings.append(this->createCheckBox(
|
||||
"Show notification", getSettings()->notificationToast));
|
||||
|
|
Loading…
Reference in a new issue