Add setting to prevent or highlight message overflow (#3418)

Co-authored-by: Rasmus Karlsson <rasmus.karlsson@pajlada.com>
This commit is contained in:
Adam Davies 2022-11-13 05:47:46 -06:00 committed by GitHub
parent d409e3f17d
commit a9d3c00369
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 90 additions and 1 deletions

View file

@ -81,6 +81,7 @@
- Minor: Migrated /mods to Helix API. (#4103)
- Minor: Improved text selection to match Windows native behaviour. (#4127)
- Minor: Add settings tooltips. (#3437)
- Minor: Add setting to limit message input length. (#3418)
- Minor: Improved look of tabs when using a layout other than top. (#3925)
- Bugfix: Fixed `Add new account` dialog causing main chatterino window to be non movable. (#4121)
- Bugfix: Connection to Twitch PubSub now recovers more reliably. (#3643, #3716)

View file

@ -14,6 +14,7 @@
#include "singletons/Toasts.hpp"
#include "util/StreamerMode.hpp"
#include "widgets/Notebook.hpp"
#include "widgets/splits/SplitInput.hpp"
using TimeoutButton = std::pair<QString, int>;
@ -98,6 +99,8 @@ public:
BoolSetting showEmptyInput = {"/appearance/showEmptyInputBox", true};
BoolSetting showMessageLength = {"/appearance/messages/showMessageLength",
false};
EnumSetting<MessageOverflow> messageOverflow = {
"/appearance/messages/messageOverflow", MessageOverflow::Highlight};
BoolSetting separateMessages = {"/appearance/messages/separateMessages",
false};
BoolSetting hideModerated = {"/appearance/messages/hideModerated", false};

View file

@ -19,6 +19,7 @@
#include "widgets/BaseWindow.hpp"
#include "widgets/helper/Line.hpp"
#include "widgets/settingspages/GeneralPageView.hpp"
#include "widgets/splits/SplitInput.hpp"
#include <QDesktopServices>
#include <QFileDialog>
@ -261,6 +262,18 @@ void GeneralPage::initLayout(GeneralPageView &layout)
layout.addCheckbox(
"Allow sending duplicate messages", s.allowDuplicateMessages, false,
"Allow a single message to be repeatedly sent without any changes.");
layout.addDropdown<std::underlying_type<MessageOverflow>::type>(
"Message overflow", {"Highlight", "Prevent", "Allow"},
s.messageOverflow,
[](auto index) {
return index;
},
[](auto args) {
return static_cast<MessageOverflow>(args.index);
},
false,
"Specify how Chatterino will handle messages that exceed Twitch "
"message limits");
layout.addTitle("Messages");
layout.addCheckbox("Separate with lines", s.separateMessages);

View file

@ -29,7 +29,6 @@
#include <QPainter>
namespace chatterino {
const int TWITCH_MESSAGE_LIMIT = 500;
SplitInput::SplitInput(Split *_chatWidget, bool enableInlineReplying)
: SplitInput(_chatWidget, _chatWidget, enableInlineReplying)
@ -848,6 +847,13 @@ void SplitInput::editTextChanged()
// set textLengthLabel value
QString text = this->ui_.textEdit->toPlainText();
if (this->shouldPreventInput(text))
{
this->ui_.textEdit->setPlainText(text.left(TWITCH_MESSAGE_LIMIT));
this->ui_.textEdit->moveCursor(QTextCursor::EndOfBlock);
return;
}
if (text.startsWith("/r ", Qt::CaseInsensitive) &&
this->split_->getChannel()->isTwitchChannel())
{
@ -867,6 +873,28 @@ void SplitInput::editTextChanged()
app->commands->execCommand(text, this->split_->getChannel(), true);
}
if (getSettings()->messageOverflow.getValue() == MessageOverflow::Highlight)
{
if (text.length() > TWITCH_MESSAGE_LIMIT &&
text.length() > this->lastOverflowLength)
{
QTextCharFormat format;
format.setForeground(Qt::red);
QTextCursor cursor = this->ui_.textEdit->textCursor();
cursor.setPosition(lastOverflowLength, QTextCursor::MoveAnchor);
cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
this->lastOverflowLength = text.length();
cursor.setCharFormat(format);
}
else if (this->lastOverflowLength != TWITCH_MESSAGE_LIMIT)
{
this->lastOverflowLength = TWITCH_MESSAGE_LIMIT;
}
}
QString labelText;
if (text.length() > 0 && getSettings()->showMessageLength)
@ -1012,4 +1040,27 @@ void SplitInput::clearInput()
}
}
bool SplitInput::shouldPreventInput(const QString &text) const
{
if (getSettings()->messageOverflow.getValue() != MessageOverflow::Prevent)
{
return false;
}
auto channel = this->split_->getChannel();
if (channel == nullptr)
{
return false;
}
if (!channel->isTwitchChannel())
{
// Don't respect this setting for IRC channels as the limits might be server-specific
return false;
}
return text.length() > TWITCH_MESSAGE_LIMIT;
}
} // namespace chatterino

View file

@ -22,6 +22,19 @@ class EffectLabel;
class MessageThread;
class ResizingTextEdit;
// MessageOverflow is used for controlling how to guide the user into not
// sending a message that will be discarded by Twitch
enum MessageOverflow {
// Allow overflowing characters to be inserted into the input box, but highlight them in red
Highlight,
// Prevent more characters from being inserted into the input box
Prevent,
// Do nothing
Allow,
};
class SplitInput : public BaseWidget
{
Q_OBJECT
@ -36,6 +49,8 @@ public:
QString getInputText() const;
void insertText(const QString &text);
static const int TWITCH_MESSAGE_LIMIT = 500;
void setReply(std::shared_ptr<MessageThread> reply,
bool showInlineReplying = true);
void setPlaceholderText(const QString &text);
@ -101,6 +116,10 @@ protected:
// This does not take hidden into account, so callers must take hidden into account themselves
int scaledMaxHeight() const;
// Returns true if the channel this input is connected to is a Twitch channel,
// the user's setting is set to Prevent, and the given text goes beyond the Twitch message length limit
bool shouldPreventInput(const QString &text) const;
Split *const split_;
QObjectRef<EmotePopup> emotePopup_;
QObjectRef<InputCompletionPopup> inputCompletionPopup_;
@ -127,6 +146,8 @@ protected:
QString currMsg_;
int prevIndex_ = 0;
int lastOverflowLength = TWITCH_MESSAGE_LIMIT;
// Hidden denotes whether this split input should be hidden or not
// This is used instead of the regular QWidget::hide/show because
// focus events don't work as expected, so instead we use this bool and