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
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 120 additions and 96 deletions

View file

@ -5,6 +5,7 @@
- Major: Release plugins alpha. (#5288)
- Major: Improve high-DPI support on Windows. (#4868)
- 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)
- Dev: Use Qt's high DPI scaling. (#4868)
- Dev: Add doxygen build target. (#5377)

View file

@ -763,10 +763,7 @@ void MessageBuilder::addTextOrEmoji(const QString &string_)
auto &&textColor = this->textColor_;
if (string.startsWith('@'))
{
this->emplace<TextElement>(string, MessageElementFlag::BoldUsername,
textColor, FontStyle::ChatMediumBold);
this->emplace<TextElement>(string, MessageElementFlag::NonBoldUsername,
textColor);
this->emplace<MentionElement>(string, textColor, textColor);
}
else
{

View file

@ -703,6 +703,38 @@ Link LinkElement::getLink() const
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
TimestampElement::TimestampElement(QTime time)
: MessageElement(MessageElementFlag::Timestamp)

View file

@ -133,9 +133,10 @@ enum class MessageElementFlag : int64_t {
// needed
Collapsed = (1LL << 26),
// used for dynamic bold usernames
BoldUsername = (1LL << 27),
NonBoldUsername = (1LL << 28),
// A mention of a username that isn't the author of the message
Mention = (1LL << 27),
// Unused = (1LL << 28),
// used to check if links should be lowercased
LowercaseLinks = (1LL << 29),
@ -236,7 +237,6 @@ public:
protected:
QStringList words_;
private:
MessageColor color_;
FontStyle style_;
};
@ -301,6 +301,42 @@ private:
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 :
// a) are images for the emote type enabled
// b) which size it wants

View file

@ -756,9 +756,7 @@ void MessageLayoutContainer::reorderRTL(int firstTextIndex)
const auto neutral = isNeutral(element->getText());
const auto neutralOrUsername =
neutral ||
element->getFlags().hasAny({MessageElementFlag::BoldUsername,
MessageElementFlag::NonBoldUsername});
neutral || element->getFlags().has(MessageElementFlag::Mention);
if (neutral &&
((this->first == FirstWord::RTL && !this->wasPrevReversed_) ||

View file

@ -51,6 +51,8 @@ using namespace chatterino::literals;
namespace {
const QColor AUTOMOD_USER_COLOR{"blue"};
using namespace std::chrono_literals;
const QString regexHelpString("(\\w+)[.,!?;:]*?$");
@ -756,7 +758,7 @@ void TwitchMessageBuilder::addTextOrEmoji(const QString &string_)
QString username = match.captured(1);
auto originalTextColor = textColor;
if (this->twitchChannel != nullptr && getSettings()->colorUsernames)
if (this->twitchChannel != nullptr)
{
if (auto userColor =
this->twitchChannel->getUserColor(username);
@ -767,21 +769,17 @@ void TwitchMessageBuilder::addTextOrEmoji(const QString &string_)
}
auto prefixedUsername = '@' + username;
this->emplace<TextElement>(prefixedUsername,
MessageElementFlag::BoldUsername,
textColor, FontStyle::ChatMediumBold)
auto remainder = string.remove(prefixedUsername);
this->emplace<MentionElement>(prefixedUsername, originalTextColor,
textColor)
->setLink({Link::UserInfo, username})
->setTrailingSpace(false);
->setTrailingSpace(remainder.isEmpty());
this->emplace<TextElement>(prefixedUsername,
MessageElementFlag::NonBoldUsername,
textColor)
->setLink({Link::UserInfo, username})
->setTrailingSpace(false);
this->emplace<TextElement>(string.remove(prefixedUsername),
MessageElementFlag::Text,
originalTextColor);
if (!remainder.isEmpty())
{
this->emplace<TextElement>(remainder, MessageElementFlag::Text,
originalTextColor);
}
return;
}
@ -797,30 +795,23 @@ void TwitchMessageBuilder::addTextOrEmoji(const QString &string_)
{
auto originalTextColor = textColor;
if (getSettings()->colorUsernames)
if (auto userColor = this->twitchChannel->getUserColor(username);
userColor.isValid())
{
if (auto userColor =
this->twitchChannel->getUserColor(username);
userColor.isValid())
{
textColor = userColor;
}
textColor = userColor;
}
this->emplace<TextElement>(username,
MessageElementFlag::BoldUsername,
textColor, FontStyle::ChatMediumBold)
auto remainder = string.remove(username);
this->emplace<MentionElement>(username, originalTextColor,
textColor)
->setLink({Link::UserInfo, username})
->setTrailingSpace(false);
->setTrailingSpace(remainder.isEmpty());
this->emplace<TextElement>(
username, MessageElementFlag::NonBoldUsername, textColor)
->setLink({Link::UserInfo, username})
->setTrailingSpace(false);
this->emplace<TextElement>(string.remove(username),
MessageElementFlag::Text,
originalTextColor);
if (!remainder.isEmpty())
{
this->emplace<TextElement>(remainder, MessageElementFlag::Text,
originalTextColor);
}
return;
}
@ -1821,7 +1812,7 @@ void TwitchMessageBuilder::listOfUsersSystemMessage(QString prefix,
MessageColor color = MessageColor::System;
if (tc && getSettings()->colorUsernames)
if (tc)
{
if (auto userColor = tc->getUserColor(username);
userColor.isValid())
@ -1830,14 +1821,7 @@ void TwitchMessageBuilder::listOfUsersSystemMessage(QString prefix,
}
}
builder
->emplace<TextElement>(username, MessageElementFlag::BoldUsername,
color, FontStyle::ChatMediumBold)
->setLink({Link::UserInfo, username})
->setTrailingSpace(false);
builder
->emplace<TextElement>(username,
MessageElementFlag::NonBoldUsername, color)
builder->emplace<MentionElement>(username, MessageColor::System, color)
->setLink({Link::UserInfo, username})
->setTrailingSpace(false);
}
@ -1873,7 +1857,7 @@ void TwitchMessageBuilder::listOfUsersSystemMessage(
MessageColor color = MessageColor::System;
if (tc && getSettings()->colorUsernames)
if (tc)
{
if (auto userColor = tc->getUserColor(user.userLogin);
userColor.isValid())
@ -1883,14 +1867,8 @@ void TwitchMessageBuilder::listOfUsersSystemMessage(
}
builder
->emplace<TextElement>(user.userName,
MessageElementFlag::BoldUsername, color,
FontStyle::ChatMediumBold)
->setLink({Link::UserInfo, user.userLogin})
->setTrailingSpace(false);
builder
->emplace<TextElement>(user.userName,
MessageElementFlag::NonBoldUsername, color)
->emplace<MentionElement>(user.userName, MessageColor::System,
color)
->setLink({Link::UserInfo, user.userLogin})
->setTrailingSpace(false);
}
@ -1960,12 +1938,8 @@ MessagePtr TwitchMessageBuilder::makeAutomodInfoMessage(
builder.emplace<BadgeElement>(makeAutoModBadge(),
MessageElementFlag::BadgeChannelAuthority);
// AutoMod "username"
builder.emplace<TextElement>("AutoMod:", MessageElementFlag::BoldUsername,
MessageColor(QColor("blue")),
FontStyle::ChatMediumBold);
builder.emplace<TextElement>(
"AutoMod:", MessageElementFlag::NonBoldUsername,
MessageColor(QColor("blue")));
builder.emplace<MentionElement>("AutoMod:", AUTOMOD_USER_COLOR,
AUTOMOD_USER_COLOR);
switch (action.type)
{
case AutomodInfoAction::OnHold: {
@ -2019,12 +1993,8 @@ std::pair<MessagePtr, MessagePtr> TwitchMessageBuilder::makeAutomodMessage(
builder.emplace<BadgeElement>(makeAutoModBadge(),
MessageElementFlag::BadgeChannelAuthority);
// AutoMod "username"
builder.emplace<TextElement>("AutoMod:", MessageElementFlag::BoldUsername,
MessageColor(QColor("blue")),
FontStyle::ChatMediumBold);
builder.emplace<TextElement>(
"AutoMod:", MessageElementFlag::NonBoldUsername,
MessageColor(QColor("blue")));
builder2.emplace<MentionElement>("AutoMod:", AUTOMOD_USER_COLOR,
AUTOMOD_USER_COLOR);
// AutoMod header message
builder.emplace<TextElement>(
("Held a message for reason: " + action.reason +
@ -2072,14 +2042,8 @@ std::pair<MessagePtr, MessagePtr> TwitchMessageBuilder::makeAutomodMessage(
// sender username
builder2
.emplace<TextElement>(
action.target.displayName + ":", MessageElementFlag::BoldUsername,
MessageColor(action.target.color), FontStyle::ChatMediumBold)
->setLink({Link::UserInfo, action.target.login});
builder2
.emplace<TextElement>(action.target.displayName + ":",
MessageElementFlag::NonBoldUsername,
MessageColor(action.target.color))
.emplace<MentionElement>(action.target.displayName + ":",
MessageColor::Text, action.target.color)
->setLink({Link::UserInfo, action.target.login});
// sender's message caught by AutoMod
builder2.emplace<TextElement>(action.message, MessageElementFlag::Text,
@ -2275,17 +2239,9 @@ std::pair<MessagePtr, MessagePtr> TwitchMessageBuilder::makeLowTrustUserMessage(
appendBadges(&builder2, action.senderBadges, {}, twitchChannel);
// sender username
builder2
.emplace<TextElement>(action.suspiciousUserDisplayName + ":",
MessageElementFlag::BoldUsername,
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});
builder2.emplace<MentionElement>(action.suspiciousUserDisplayName + ":",
MessageColor::Text,
action.suspiciousUserColor);
// sender's message caught by AutoMod
for (const auto &fragment : action.fragments)

View file

@ -108,7 +108,6 @@ WindowManager::WindowManager(const Paths &paths)
this->wordFlagsListener_.addSetting(settings->showBadgesFfz);
this->wordFlagsListener_.addSetting(settings->showBadgesSevenTV);
this->wordFlagsListener_.addSetting(settings->enableEmoteImages);
this->wordFlagsListener_.addSetting(settings->boldUsernames);
this->wordFlagsListener_.addSetting(settings->lowercaseDomains);
this->wordFlagsListener_.addSetting(settings->showReplyButton);
this->wordFlagsListener_.setCB([this] {
@ -182,8 +181,6 @@ void WindowManager::updateWordTypeMask()
// misc
flags.set(MEF::AlwaysShow);
flags.set(MEF::Collapsed);
flags.set(settings->boldUsernames ? MEF::BoldUsername
: MEF::NonBoldUsername);
flags.set(MEF::LowercaseLinks, settings->lowercaseDomains);
flags.set(MEF::ChannelPointReward);
@ -422,6 +419,13 @@ void WindowManager::initialize(Settings &settings, const Paths &paths)
this->forceLayoutChannelViews();
});
settings.colorUsernames.connect([this](auto, auto) {
this->forceLayoutChannelViews();
});
settings.boldUsernames.connect([this](auto, auto) {
this->forceLayoutChannelViews();
});
this->initialized_ = true;
}