fix: update color of usernames & boldness of usernames on the fly (#5300)

This commit is contained in:
pajlada
2024-05-12 14:37:47 +02:00
committed by GitHub
parent febcf464fe
commit 3d5acff907
7 changed files with 120 additions and 96 deletions
+1
View File
@@ -5,6 +5,7 @@
- Major: Release plugins alpha. (#5288) - Major: Release plugins alpha. (#5288)
- Major: Improve high-DPI support on Windows. (#4868) - Major: Improve high-DPI support on Windows. (#4868)
- Minor: Add option to customise Moderation buttons with images. (#5369) - Minor: Add option to customise Moderation buttons with images. (#5369)
- Minor: Colored usernames now update on the fly when changing the "Color @usernames" setting. (#5300)
- Bugfix: If a network request errors with 200 OK, Qt's error code is now reported instead of the HTTP status. (#5378) - Bugfix: If a network request errors with 200 OK, Qt's error code is now reported instead of the HTTP status. (#5378)
- Dev: Use Qt's high DPI scaling. (#4868) - Dev: Use Qt's high DPI scaling. (#4868)
- Dev: Add doxygen build target. (#5377) - Dev: Add doxygen build target. (#5377)
+1 -4
View File
@@ -763,10 +763,7 @@ void MessageBuilder::addTextOrEmoji(const QString &string_)
auto &&textColor = this->textColor_; auto &&textColor = this->textColor_;
if (string.startsWith('@')) if (string.startsWith('@'))
{ {
this->emplace<TextElement>(string, MessageElementFlag::BoldUsername, this->emplace<MentionElement>(string, textColor, textColor);
textColor, FontStyle::ChatMediumBold);
this->emplace<TextElement>(string, MessageElementFlag::NonBoldUsername,
textColor);
} }
else else
{ {
+32
View File
@@ -703,6 +703,38 @@ Link LinkElement::getLink() const
return {Link::Url, this->linkInfo_.url()}; return {Link::Url, this->linkInfo_.url()};
} }
MentionElement::MentionElement(const QString &name, MessageColor fallbackColor_,
MessageColor userColor_)
: TextElement(name, {MessageElementFlag::Text, MessageElementFlag::Mention})
, fallbackColor(fallbackColor_)
, userColor(userColor_)
{
}
void MentionElement::addToContainer(MessageLayoutContainer &container,
MessageElementFlags flags)
{
if (getSettings()->colorUsernames)
{
this->color_ = this->userColor;
}
else
{
this->color_ = this->fallbackColor;
}
if (getSettings()->boldUsernames)
{
this->style_ = FontStyle::ChatMediumBold;
}
else
{
this->style_ = FontStyle::ChatMedium;
}
TextElement::addToContainer(container, flags);
}
// TIMESTAMP // TIMESTAMP
TimestampElement::TimestampElement(QTime time) TimestampElement::TimestampElement(QTime time)
: MessageElement(MessageElementFlag::Timestamp) : MessageElement(MessageElementFlag::Timestamp)
+40 -4
View File
@@ -133,9 +133,10 @@ enum class MessageElementFlag : int64_t {
// needed // needed
Collapsed = (1LL << 26), Collapsed = (1LL << 26),
// used for dynamic bold usernames // A mention of a username that isn't the author of the message
BoldUsername = (1LL << 27), Mention = (1LL << 27),
NonBoldUsername = (1LL << 28),
// Unused = (1LL << 28),
// used to check if links should be lowercased // used to check if links should be lowercased
LowercaseLinks = (1LL << 29), LowercaseLinks = (1LL << 29),
@@ -236,7 +237,6 @@ public:
protected: protected:
QStringList words_; QStringList words_;
private:
MessageColor color_; MessageColor color_;
FontStyle style_; FontStyle style_;
}; };
@@ -301,6 +301,42 @@ private:
QStringList original_; QStringList original_;
}; };
/**
* @brief Contains a username mention.
*
* Examples of mentions:
* V
* 13:37 pajlada: hello @forsen
*
* V V
* 13:37 The moderators of this channel are: forsen, nuuls
*/
class MentionElement : public TextElement
{
public:
MentionElement(const QString &name, MessageColor fallbackColor_,
MessageColor userColor_);
~MentionElement() override = default;
MentionElement(const MentionElement &) = delete;
MentionElement(MentionElement &&) = delete;
MentionElement &operator=(const MentionElement &) = delete;
MentionElement &operator=(MentionElement &&) = delete;
void addToContainer(MessageLayoutContainer &container,
MessageElementFlags flags) override;
private:
/**
* The color of the element in case the "Colorize @usernames" is disabled
**/
MessageColor fallbackColor;
/**
* The color of the element in case the "Colorize @usernames" is enabled
**/
MessageColor userColor;
};
// contains emote data and will pick the emote based on : // contains emote data and will pick the emote based on :
// a) are images for the emote type enabled // a) are images for the emote type enabled
// b) which size it wants // b) which size it wants
@@ -756,9 +756,7 @@ void MessageLayoutContainer::reorderRTL(int firstTextIndex)
const auto neutral = isNeutral(element->getText()); const auto neutral = isNeutral(element->getText());
const auto neutralOrUsername = const auto neutralOrUsername =
neutral || neutral || element->getFlags().has(MessageElementFlag::Mention);
element->getFlags().hasAny({MessageElementFlag::BoldUsername,
MessageElementFlag::NonBoldUsername});
if (neutral && if (neutral &&
((this->first == FirstWord::RTL && !this->wasPrevReversed_) || ((this->first == FirstWord::RTL && !this->wasPrevReversed_) ||
+38 -82
View File
@@ -51,6 +51,8 @@ using namespace chatterino::literals;
namespace { namespace {
const QColor AUTOMOD_USER_COLOR{"blue"};
using namespace std::chrono_literals; using namespace std::chrono_literals;
const QString regexHelpString("(\\w+)[.,!?;:]*?$"); const QString regexHelpString("(\\w+)[.,!?;:]*?$");
@@ -756,7 +758,7 @@ void TwitchMessageBuilder::addTextOrEmoji(const QString &string_)
QString username = match.captured(1); QString username = match.captured(1);
auto originalTextColor = textColor; auto originalTextColor = textColor;
if (this->twitchChannel != nullptr && getSettings()->colorUsernames) if (this->twitchChannel != nullptr)
{ {
if (auto userColor = if (auto userColor =
this->twitchChannel->getUserColor(username); this->twitchChannel->getUserColor(username);
@@ -767,21 +769,17 @@ void TwitchMessageBuilder::addTextOrEmoji(const QString &string_)
} }
auto prefixedUsername = '@' + username; auto prefixedUsername = '@' + username;
this->emplace<TextElement>(prefixedUsername, auto remainder = string.remove(prefixedUsername);
MessageElementFlag::BoldUsername, this->emplace<MentionElement>(prefixedUsername, originalTextColor,
textColor, FontStyle::ChatMediumBold) textColor)
->setLink({Link::UserInfo, username}) ->setLink({Link::UserInfo, username})
->setTrailingSpace(false); ->setTrailingSpace(remainder.isEmpty());
this->emplace<TextElement>(prefixedUsername, if (!remainder.isEmpty())
MessageElementFlag::NonBoldUsername, {
textColor) this->emplace<TextElement>(remainder, MessageElementFlag::Text,
->setLink({Link::UserInfo, username}) originalTextColor);
->setTrailingSpace(false); }
this->emplace<TextElement>(string.remove(prefixedUsername),
MessageElementFlag::Text,
originalTextColor);
return; return;
} }
@@ -797,30 +795,23 @@ void TwitchMessageBuilder::addTextOrEmoji(const QString &string_)
{ {
auto originalTextColor = textColor; auto originalTextColor = textColor;
if (getSettings()->colorUsernames) if (auto userColor = this->twitchChannel->getUserColor(username);
userColor.isValid())
{ {
if (auto userColor = textColor = userColor;
this->twitchChannel->getUserColor(username);
userColor.isValid())
{
textColor = userColor;
}
} }
this->emplace<TextElement>(username, auto remainder = string.remove(username);
MessageElementFlag::BoldUsername, this->emplace<MentionElement>(username, originalTextColor,
textColor, FontStyle::ChatMediumBold) textColor)
->setLink({Link::UserInfo, username}) ->setLink({Link::UserInfo, username})
->setTrailingSpace(false); ->setTrailingSpace(remainder.isEmpty());
this->emplace<TextElement>( if (!remainder.isEmpty())
username, MessageElementFlag::NonBoldUsername, textColor) {
->setLink({Link::UserInfo, username}) this->emplace<TextElement>(remainder, MessageElementFlag::Text,
->setTrailingSpace(false); originalTextColor);
}
this->emplace<TextElement>(string.remove(username),
MessageElementFlag::Text,
originalTextColor);
return; return;
} }
@@ -1821,7 +1812,7 @@ void TwitchMessageBuilder::listOfUsersSystemMessage(QString prefix,
MessageColor color = MessageColor::System; MessageColor color = MessageColor::System;
if (tc && getSettings()->colorUsernames) if (tc)
{ {
if (auto userColor = tc->getUserColor(username); if (auto userColor = tc->getUserColor(username);
userColor.isValid()) userColor.isValid())
@@ -1830,14 +1821,7 @@ void TwitchMessageBuilder::listOfUsersSystemMessage(QString prefix,
} }
} }
builder builder->emplace<MentionElement>(username, MessageColor::System, color)
->emplace<TextElement>(username, MessageElementFlag::BoldUsername,
color, FontStyle::ChatMediumBold)
->setLink({Link::UserInfo, username})
->setTrailingSpace(false);
builder
->emplace<TextElement>(username,
MessageElementFlag::NonBoldUsername, color)
->setLink({Link::UserInfo, username}) ->setLink({Link::UserInfo, username})
->setTrailingSpace(false); ->setTrailingSpace(false);
} }
@@ -1873,7 +1857,7 @@ void TwitchMessageBuilder::listOfUsersSystemMessage(
MessageColor color = MessageColor::System; MessageColor color = MessageColor::System;
if (tc && getSettings()->colorUsernames) if (tc)
{ {
if (auto userColor = tc->getUserColor(user.userLogin); if (auto userColor = tc->getUserColor(user.userLogin);
userColor.isValid()) userColor.isValid())
@@ -1883,14 +1867,8 @@ void TwitchMessageBuilder::listOfUsersSystemMessage(
} }
builder builder
->emplace<TextElement>(user.userName, ->emplace<MentionElement>(user.userName, MessageColor::System,
MessageElementFlag::BoldUsername, color, color)
FontStyle::ChatMediumBold)
->setLink({Link::UserInfo, user.userLogin})
->setTrailingSpace(false);
builder
->emplace<TextElement>(user.userName,
MessageElementFlag::NonBoldUsername, color)
->setLink({Link::UserInfo, user.userLogin}) ->setLink({Link::UserInfo, user.userLogin})
->setTrailingSpace(false); ->setTrailingSpace(false);
} }
@@ -1960,12 +1938,8 @@ MessagePtr TwitchMessageBuilder::makeAutomodInfoMessage(
builder.emplace<BadgeElement>(makeAutoModBadge(), builder.emplace<BadgeElement>(makeAutoModBadge(),
MessageElementFlag::BadgeChannelAuthority); MessageElementFlag::BadgeChannelAuthority);
// AutoMod "username" // AutoMod "username"
builder.emplace<TextElement>("AutoMod:", MessageElementFlag::BoldUsername, builder.emplace<MentionElement>("AutoMod:", AUTOMOD_USER_COLOR,
MessageColor(QColor("blue")), AUTOMOD_USER_COLOR);
FontStyle::ChatMediumBold);
builder.emplace<TextElement>(
"AutoMod:", MessageElementFlag::NonBoldUsername,
MessageColor(QColor("blue")));
switch (action.type) switch (action.type)
{ {
case AutomodInfoAction::OnHold: { case AutomodInfoAction::OnHold: {
@@ -2019,12 +1993,8 @@ std::pair<MessagePtr, MessagePtr> TwitchMessageBuilder::makeAutomodMessage(
builder.emplace<BadgeElement>(makeAutoModBadge(), builder.emplace<BadgeElement>(makeAutoModBadge(),
MessageElementFlag::BadgeChannelAuthority); MessageElementFlag::BadgeChannelAuthority);
// AutoMod "username" // AutoMod "username"
builder.emplace<TextElement>("AutoMod:", MessageElementFlag::BoldUsername, builder2.emplace<MentionElement>("AutoMod:", AUTOMOD_USER_COLOR,
MessageColor(QColor("blue")), AUTOMOD_USER_COLOR);
FontStyle::ChatMediumBold);
builder.emplace<TextElement>(
"AutoMod:", MessageElementFlag::NonBoldUsername,
MessageColor(QColor("blue")));
// AutoMod header message // AutoMod header message
builder.emplace<TextElement>( builder.emplace<TextElement>(
("Held a message for reason: " + action.reason + ("Held a message for reason: " + action.reason +
@@ -2072,14 +2042,8 @@ std::pair<MessagePtr, MessagePtr> TwitchMessageBuilder::makeAutomodMessage(
// sender username // sender username
builder2 builder2
.emplace<TextElement>( .emplace<MentionElement>(action.target.displayName + ":",
action.target.displayName + ":", MessageElementFlag::BoldUsername, MessageColor::Text, action.target.color)
MessageColor(action.target.color), FontStyle::ChatMediumBold)
->setLink({Link::UserInfo, action.target.login});
builder2
.emplace<TextElement>(action.target.displayName + ":",
MessageElementFlag::NonBoldUsername,
MessageColor(action.target.color))
->setLink({Link::UserInfo, action.target.login}); ->setLink({Link::UserInfo, action.target.login});
// sender's message caught by AutoMod // sender's message caught by AutoMod
builder2.emplace<TextElement>(action.message, MessageElementFlag::Text, builder2.emplace<TextElement>(action.message, MessageElementFlag::Text,
@@ -2275,17 +2239,9 @@ std::pair<MessagePtr, MessagePtr> TwitchMessageBuilder::makeLowTrustUserMessage(
appendBadges(&builder2, action.senderBadges, {}, twitchChannel); appendBadges(&builder2, action.senderBadges, {}, twitchChannel);
// sender username // sender username
builder2 builder2.emplace<MentionElement>(action.suspiciousUserDisplayName + ":",
.emplace<TextElement>(action.suspiciousUserDisplayName + ":", MessageColor::Text,
MessageElementFlag::BoldUsername, action.suspiciousUserColor);
MessageColor(action.suspiciousUserColor),
FontStyle::ChatMediumBold)
->setLink({Link::UserInfo, action.suspiciousUserLogin});
builder2
.emplace<TextElement>(action.suspiciousUserDisplayName + ":",
MessageElementFlag::NonBoldUsername,
MessageColor(action.suspiciousUserColor))
->setLink({Link::UserInfo, action.suspiciousUserLogin});
// sender's message caught by AutoMod // sender's message caught by AutoMod
for (const auto &fragment : action.fragments) for (const auto &fragment : action.fragments)
+7 -3
View File
@@ -108,7 +108,6 @@ WindowManager::WindowManager(const Paths &paths)
this->wordFlagsListener_.addSetting(settings->showBadgesFfz); this->wordFlagsListener_.addSetting(settings->showBadgesFfz);
this->wordFlagsListener_.addSetting(settings->showBadgesSevenTV); this->wordFlagsListener_.addSetting(settings->showBadgesSevenTV);
this->wordFlagsListener_.addSetting(settings->enableEmoteImages); this->wordFlagsListener_.addSetting(settings->enableEmoteImages);
this->wordFlagsListener_.addSetting(settings->boldUsernames);
this->wordFlagsListener_.addSetting(settings->lowercaseDomains); this->wordFlagsListener_.addSetting(settings->lowercaseDomains);
this->wordFlagsListener_.addSetting(settings->showReplyButton); this->wordFlagsListener_.addSetting(settings->showReplyButton);
this->wordFlagsListener_.setCB([this] { this->wordFlagsListener_.setCB([this] {
@@ -182,8 +181,6 @@ void WindowManager::updateWordTypeMask()
// misc // misc
flags.set(MEF::AlwaysShow); flags.set(MEF::AlwaysShow);
flags.set(MEF::Collapsed); flags.set(MEF::Collapsed);
flags.set(settings->boldUsernames ? MEF::BoldUsername
: MEF::NonBoldUsername);
flags.set(MEF::LowercaseLinks, settings->lowercaseDomains); flags.set(MEF::LowercaseLinks, settings->lowercaseDomains);
flags.set(MEF::ChannelPointReward); flags.set(MEF::ChannelPointReward);
@@ -422,6 +419,13 @@ void WindowManager::initialize(Settings &settings, const Paths &paths)
this->forceLayoutChannelViews(); this->forceLayoutChannelViews();
}); });
settings.colorUsernames.connect([this](auto, auto) {
this->forceLayoutChannelViews();
});
settings.boldUsernames.connect([this](auto, auto) {
this->forceLayoutChannelViews();
});
this->initialized_ = true; this->initialized_ = true;
} }