feat: add setting to pulse split input on self message received (#6380)

This commit is contained in:
pajlada
2025-08-18 01:24:39 +02:00
committed by GitHub
parent 1b9ed11a67
commit 1afac3382e
15 changed files with 136 additions and 13 deletions
+1
View File
@@ -23,6 +23,7 @@
- Minor: Message character length label is now monospaced. (#6366)
- Minor: Add a setting under Moderation -> Logs to customize the timestamp used for chat logs. (#6338)
- Minor: Add a setting under Moderation -> Logs to use server timestamp from the message instead of the local clock time for logging. (#6346)
- Minor: Add a setting under Chat that, when enabled, pulses the text input whenever one of your messages is successfully sent to the chat. (#6380)
- Minor: Add feature to search for only zero-width emotes when prepended by `:~`. (#6362)
- Minor: The follow and sub dates now show the duration in a tooltip. (#6384)
- Minor: Usercards now show a live indicator if the user is currently streaming. (#6383)
+1
View File
@@ -351,6 +351,7 @@
"additionalProperties": false,
"properties": {
"background": { "$ref": "#/definitions/qt-color" },
"backgroundPulse": { "$ref": "#/definitions/qt-color" },
"text": { "$ref": "#/definitions/qt-color" }
},
"required": ["background", "text"]
+1
View File
@@ -59,6 +59,7 @@
},
"input": {
"background": "#080808",
"backgroundPulse": "#083808",
"text": "#ffffff"
},
"messageSeperator": "#3c3c3c",
+1
View File
@@ -59,6 +59,7 @@
},
"input": {
"background": "#242424",
"backgroundPulse": "#245424",
"text": "#ffffff"
},
"messageSeperator": "#3c3c3c",
+1
View File
@@ -59,6 +59,7 @@
},
"input": {
"background": "#dbdbdb",
"backgroundPulse": "#dbffdb",
"text": "#000000"
},
"messageSeperator": "#7f7f7f",
+1
View File
@@ -59,6 +59,7 @@
},
"input": {
"background": "#f2f2f2",
"backgroundPulse": "#d2ffd2",
"text": "#000000"
},
"messageSeperator": "#7f7f7f",
+5
View File
@@ -285,6 +285,11 @@ public:
false,
};
BoolSetting pulseTextInputOnSelfMessage = {
"/appearance/pulseTextInputOnSelfMessage",
false,
};
/// Behaviour
BoolSetting allowDuplicateMessages = {"/behaviour/allowDuplicateMessages",
true};
+1
View File
@@ -205,6 +205,7 @@ void parseSplits(const QJsonObject &splits, const QJsonObject &splitsFallback,
const auto input = splits["input"_L1].toObject();
const auto inputFallback = splitsFallback["input"_L1].toObject();
parseColor(theme.splits, input, background);
parseColor(theme.splits, input, backgroundPulse);
parseColor(theme.splits, input, text);
}
}
+2
View File
@@ -146,7 +146,9 @@ public:
struct {
QColor background;
QColor backgroundPulse;
QColor text;
// Used by the ChatterListWidget & QuickSwitcherPopup
QString styleSheet;
} input;
} splits;
+1
View File
@@ -975,6 +975,7 @@ void ChannelView::setChannel(const ChannelPtr &underlyingChannel)
}
this->channel_->addMessage(message, MessageContext::Repost,
overridingFlags);
this->messageAddedToChannel(message);
}
});
+3
View File
@@ -228,6 +228,9 @@ public:
pajlada::Signals::Signal<QString, FromTwitchLinkOpenChannelIn>
openChannelIn;
/// This signal fires when a message passed filters and was added to the channel view
Q_SIGNAL void messageAddedToChannel(MessagePtr &message);
protected:
void themeChangedEvent() override;
void scaleChangedEvent(float scale) override;
@@ -496,6 +496,14 @@ void GeneralPage::initLayout(GeneralPageView &layout)
->addKeywords({"scroll bar"})
->addTo(layout);
SettingWidget::checkbox(
"Pulse text input when one of your messages is successfully sent",
s.pulseTextInputOnSelfMessage)
->setTooltip(
"Pulses the text input in a green color whenever a message of "
"yours is successfully sent in the matching channel.")
->addTo(layout);
layout.addTitle("Messages");
SettingWidget::checkbox("Separate with lines", s.separateMessages)
+15
View File
@@ -854,6 +854,21 @@ void Split::setChannel(IndirectChannel newChannel)
this->actionRequested.invoke(Action::RefreshTab);
});
QObject::connect(
this->view_, &ChannelView::messageAddedToChannel, this,
[this](MessagePtr &message) {
if (!getSettings()->pulseTextInputOnSelfMessage)
{
return;
}
auto user = getApp()->getAccounts()->twitch.getCurrent();
if (!user->isAnon() && message->userID == user->getUserId())
{
// A message from yourself was just received in this split
this->input_->triggerSelfMessageReceived();
}
});
this->channelChanged.invoke();
this->actionRequested.invoke(Action::RefreshTab);
+76 -13
View File
@@ -33,8 +33,24 @@
#include <functional>
using namespace Qt::Literals;
namespace chatterino {
namespace {
// Current function: https://www.desmos.com/calculator/vdyamchjwh
qreal highlightEasingFunction(qreal progress)
{
if (progress <= 0.1)
{
return 1.0 - pow(10.0 * progress, 3.0);
}
return 1.0 + pow((20.0 / 9.0) * (0.5 * progress - 0.5), 3.0);
}
} // namespace
SplitInput::SplitInput(Split *_chatWidget, bool enableInlineReplying)
: SplitInput(_chatWidget, _chatWidget, _chatWidget->view_,
enableInlineReplying)
@@ -47,6 +63,7 @@ SplitInput::SplitInput(QWidget *parent, Split *_chatWidget,
, split_(_chatWidget)
, channelView_(_channelView)
, enableInlineReplying_(enableInlineReplying)
, backgroundColorAnimation(this, "backgroundColor"_ba)
{
this->installEventFilter(this);
this->initLayout();
@@ -75,6 +92,11 @@ SplitInput::SplitInput(QWidget *parent, Split *_chatWidget,
this->clearShortcuts();
this->addShortcuts();
});
QEasingCurve curve;
curve.setCustomType(highlightEasingFunction);
this->backgroundColorAnimation.setDuration(500);
this->backgroundColorAnimation.setEasingCurve(curve);
}
void SplitInput::initLayout()
@@ -140,6 +162,7 @@ void SplitInput::initLayout()
hboxLayout.emplace<ResizingTextEdit>().assign(&this->ui_.textEdit);
connect(textEdit.getElement(), &ResizingTextEdit::textChanged, this,
&SplitInput::editTextChanged);
textEdit->setFrameStyle(QFrame::NoFrame);
hboxLayout.emplace<LabelButton>("SEND").assign(&this->ui_.sendButton);
this->ui_.sendButton->hide();
@@ -226,6 +249,16 @@ void SplitInput::initLayout()
this->managedConnections_);
}
void SplitInput::triggerSelfMessageReceived()
{
if (this->backgroundColorAnimation.state() != QPropertyAnimation::Stopped)
{
this->backgroundColorAnimation.stop();
}
this->backgroundColorAnimation.setDirection(QPropertyAnimation::Forward);
this->backgroundColorAnimation.start();
}
void SplitInput::scaleChangedEvent(float scale)
{
auto *app = getApp();
@@ -246,13 +279,6 @@ void SplitInput::scaleChangedEvent(float scale)
this->ui_.textEdit->setFont(
app->getFonts()->getFont(FontStyle::ChatMedium, scale));
QPalette placeholderPalette;
placeholderPalette.setColor(
QPalette::PlaceholderText,
this->theme->messages.textColors.chatPlaceholder);
this->ui_.textEdit->setStyleSheet(this->theme->splits.input.styleSheet);
this->ui_.textEdit->setPalette(placeholderPalette);
// TODO: This font does _not_ get updated when you change your chat font
// NOTE: We're using TimestampMedium here to get a font that uses the tnum font feature,
// meaning numbers get equal width & don't bounce around while the user is typing.
@@ -266,17 +292,19 @@ void SplitInput::scaleChangedEvent(float scale)
void SplitInput::themeChangedEvent()
{
QPalette palette;
QPalette placeholderPalette;
palette.setColor(QPalette::WindowText, this->theme->splits.input.text);
placeholderPalette.setColor(
QPalette::PlaceholderText,
this->theme->messages.textColors.chatPlaceholder);
this->ui_.textEditLength->setPalette(palette);
this->ui_.textEdit->setStyleSheet(this->theme->splits.input.styleSheet);
this->ui_.textEdit->setPalette(placeholderPalette);
// Theme changed, reset current background color
this->setBackgroundColor(this->theme->splits.input.background);
this->backgroundColorAnimation.setStartValue(
this->theme->splits.input.backgroundPulse);
this->backgroundColorAnimation.setEndValue(
this->theme->splits.input.background);
this->backgroundColorAnimation.stop();
this->updateTextEditPalette();
if (this->theme->isLightTheme())
{
@@ -1277,4 +1305,39 @@ int SplitInput::replyMessageWidth() const
return this->ui_.inputWrapper->width() - 1 - 10;
}
void SplitInput::updateTextEditPalette()
{
QPalette p;
// Placeholder text color
p.setColor(QPalette::PlaceholderText,
this->theme->messages.textColors.chatPlaceholder);
// Text color
p.setColor(QPalette::Text, this->theme->messages.textColors.regular);
// Selection background color
p.setBrush(QPalette::Highlight,
this->theme->isLightTheme()
? QColor(u"#68B1FF"_s)
: this->theme->tabs.selected.backgrounds.regular);
// Background color
p.setBrush(QPalette::Base, this->backgroundColor());
this->ui_.textEdit->setPalette(p);
}
QColor SplitInput::backgroundColor() const
{
return this->backgroundColor_;
}
void SplitInput::setBackgroundColor(QColor newColor)
{
this->backgroundColor_ = newColor;
this->updateTextEditPalette();
}
} // namespace chatterino
+19
View File
@@ -8,6 +8,7 @@
#include <QLineEdit>
#include <QPaintEvent>
#include <QPointer>
#include <QPropertyAnimation>
#include <QTextEdit>
#include <QVBoxLayout>
#include <QWidget>
@@ -75,6 +76,8 @@ public:
*/
void setInputText(const QString &newInputText);
void triggerSelfMessageReceived();
pajlada::Signals::Signal<const QString &> textChanged;
pajlada::Signals::NoArgSignal selectionChanged;
@@ -169,6 +172,22 @@ protected:
// set the height of the split input to 0 if we're supposed to be hidden instead
bool hidden{false};
/// Updates the text edit palette using the current theme
/// and current "backgroundColor" property
void updateTextEditPalette();
// the background color defines the current background color of this split input
// instead of reading straight from the theme, we store a property here
// to be used by a property to be able to pulse a highlight color on demand
Q_PROPERTY(
QColor backgroundColor READ backgroundColor WRITE setBackgroundColor);
QColor backgroundColor_{"#000000"};
QColor backgroundColor() const;
void setBackgroundColor(QColor newColor);
QPropertyAnimation backgroundColorAnimation;
private Q_SLOTS:
void editTextChanged();