diff --git a/src/ircmanager.cpp b/src/ircmanager.cpp index 7c93d2130..8e7472ba0 100644 --- a/src/ircmanager.cpp +++ b/src/ircmanager.cpp @@ -6,6 +6,7 @@ #include "debug/log.hpp" #include "emotemanager.hpp" #include "messages/messageparseargs.hpp" +#include "settingsmanager.hpp" #include "twitch/twitchmessagebuilder.hpp" #include "twitch/twitchparsemessage.hpp" #include "twitch/twitchuser.hpp" @@ -31,6 +32,9 @@ IrcManager::IrcManager(ChannelManager &_channelManager, Resources &_resources, , resources(_resources) , windowManager(_windowManager) { + this->messageSuffix.append(' '); + this->messageSuffix.append(QChar(0x206D)); + AccountManager::getInstance().Twitch.userChanged.connect([this]() { this->setUser(AccountManager::getInstance().Twitch.getCurrent()); @@ -177,11 +181,15 @@ void IrcManager::disconnect() this->writeConnection->close(); } -void IrcManager::sendMessage(const QString &channelName, const QString &message) +void IrcManager::sendMessage(const QString &channelName, QString message) { this->connectionMutex.lock(); + static int i = 0; if (this->writeConnection) { + if (SettingsManager::getInstance().allowDuplicateMessages && (++i % 2) == 0) { + message.append(this->messageSuffix); + } this->writeConnection->sendRaw("PRIVMSG #" + channelName + " :" + message); } diff --git a/src/ircmanager.hpp b/src/ircmanager.hpp index 00bc298dc..01f952660 100644 --- a/src/ircmanager.hpp +++ b/src/ircmanager.hpp @@ -38,7 +38,7 @@ public: bool tryRemoveIgnoredUser(QString const &username, QString &errorMessage); void removeIgnoredUser(QString const &username); - void sendMessage(const QString &channelName, const QString &message); + void sendMessage(const QString &channelName, QString message); void joinChannel(const QString &channelName); void partChannel(const QString &channelName); @@ -89,6 +89,9 @@ private: void onConnected(); void onDisconnected(); + +private: + QByteArray messageSuffix; }; } // namespace chatterino diff --git a/src/widgets/helper/splitinput.cpp b/src/widgets/helper/splitinput.cpp index 72698eaa2..74f68790a 100644 --- a/src/widgets/helper/splitinput.cpp +++ b/src/widgets/helper/splitinput.cpp @@ -198,6 +198,11 @@ void SplitInput::clearSelection() this->textInput.setTextCursor(c); } +QString SplitInput::getInputText() const +{ + return this->textInput.toPlainText(); +} + void SplitInput::refreshTheme() { QPalette palette; @@ -213,6 +218,8 @@ void SplitInput::editTextChanged() { QString text = this->textInput.toPlainText(); + this->textChanged.invoke(text); + text = text.trimmed(); static QRegularExpression spaceRegex("\\s\\s+"); text = text.replace(spaceRegex, " "); diff --git a/src/widgets/helper/splitinput.hpp b/src/widgets/helper/splitinput.hpp index 67ba30835..14e354078 100644 --- a/src/widgets/helper/splitinput.hpp +++ b/src/widgets/helper/splitinput.hpp @@ -26,6 +26,9 @@ public: SplitInput(Split *_chatWidget); void clearSelection(); + QString getInputText() const; + + pajlada::Signals::Signal textChanged; protected: virtual void paintEvent(QPaintEvent *) override; diff --git a/src/widgets/split.cpp b/src/widgets/split.cpp index 931f6331e..55f69702f 100644 --- a/src/widgets/split.cpp +++ b/src/widgets/split.cpp @@ -96,6 +96,26 @@ Split::Split(ChannelManager &_channelManager, SplitContainer *parent) this->input.clearSelection(); } }); + + this->input.textChanged.connect([this](const QString &newText) { + if (!SettingsManager::getInstance().hideEmptyInput) { + return; + } + + if (newText.length() == 0) { + this->input.hide(); + } else if (this->input.isHidden()) { + this->input.show(); + } + }); + + SettingsManager::getInstance().hideEmptyInput.connect([this](const bool &hideEmptyInput, auto) { + if (hideEmptyInput && this->input.getInputText().length() == 0) { + this->input.hide(); + } else { + this->input.show(); + } + }); } Split::~Split() @@ -294,61 +314,75 @@ void Split::doOpenStreamlink() QString path = QString::fromStdString(settings.streamlinkPath.getValue()); QString channel = QString::fromStdString(this->channelName.getValue()); QFileInfo fileinfo = QFileInfo(path); - if (fileinfo.exists() && fileinfo.isExecutable()) { - if (preferredQuality != "choose") { - QStringList args = {"twitch.tv/" + channel}; - QString quality = ""; - QString exclude = ""; - if (preferredQuality == "high") { - exclude = ">720p30"; - quality = "high,best"; - } else if (preferredQuality == "medium") { - exclude = ">540p30"; - quality = "medium,best"; - } else if (preferredQuality == "low") { - exclude = ">360p30"; - quality = "low,best"; - } else if (preferredQuality == "audio only") { - quality = "audio,audio_only"; - } else { - quality = "best"; - } - if (quality != "") - args << quality; - if (exclude != "") - args << "--stream-sorting-excludes" << exclude; - QProcess::startDetached(path, args); + + if (path.isEmpty()) { + debug::Log("[Split:doOpenStreamlink] No streamlink path selected in Settings"); + return; + } + + if (!fileinfo.exists()) { + debug::Log("[Split:doOpenStreamlink] Streamlink path ({}) is invalid, file does not exist", + path); + return; + } + + if (fileinfo.isDir() || !fileinfo.isExecutable()) { + debug::Log("[Split:doOpenStreamlink] Streamlink path ({}) is invalid, it needs to point to " + "the streamlink executable", + path); + return; + } + + if (preferredQuality != "choose") { + QStringList args = {"twitch.tv/" + channel}; + QString quality = ""; + QString exclude = ""; + if (preferredQuality == "high") { + exclude = ">720p30"; + quality = "high,best"; + } else if (preferredQuality == "medium") { + exclude = ">540p30"; + quality = "medium,best"; + } else if (preferredQuality == "low") { + exclude = ">360p30"; + quality = "low,best"; + } else if (preferredQuality == "audio only") { + quality = "audio,audio_only"; } else { - QProcess *p = new QProcess(); - // my god that signal though - QObject::connect(p, static_cast(&QProcess::finished), this, - [path, channel, p](int exitCode) { - if (exitCode > 0) { - return; - } - QString lastLine = QString(p->readAllStandardOutput()); - lastLine = lastLine.trimmed().split('\n').last(); - if (lastLine.startsWith("Available streams: ")) { - QStringList options; - QStringList split = - lastLine.right(lastLine.length() - 19).split(", "); - - for (int i = split.length() - 1; i >= 0; i--) { - QString option = split.at(i); - if (option.endsWith(" (worst)")) { - options << option.left(option.length() - 8); - } else if (option.endsWith(" (best)")) { - options << option.left(option.length() - 7); - } else { - options << option; - } - } - - QualityPopup::showDialog(channel, path, options); - } - }); - p->start(path, {"twitch.tv/" + channel}); + quality = "best"; } + if (quality != "") + args << quality; + if (exclude != "") + args << "--stream-sorting-excludes" << exclude; + QProcess::startDetached(path, args); + } else { + QProcess *p = new QProcess(); + // my god that signal though + QObject::connect(p, static_cast(&QProcess::finished), this, + [path, channel, p](int) { + QString lastLine = QString(p->readAllStandardOutput()); + lastLine = lastLine.trimmed().split('\n').last().trimmed(); + if (lastLine.startsWith("Available streams: ")) { + QStringList options; + QStringList split = + lastLine.right(lastLine.length() - 19).split(", "); + + for (int i = split.length() - 1; i >= 0; i--) { + QString option = split.at(i); + if (option.endsWith(" (worst)")) { + options << option.left(option.length() - 8); + } else if (option.endsWith(" (best)")) { + options << option.left(option.length() - 7); + } else { + options << option; + } + } + + QualityPopup::showDialog(channel, path, options); + } + }); + p->start(path, {"twitch.tv/" + channel, "--default-stream=KKona"}); } }