Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 6 commits into from
May 12, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- Major: Release plugins alpha. (#5288)
- 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: Add doxygen build target. (#5377)
- Dev: Make printing of strings in tests easier. (#5379)
Expand Down
5 changes: 1 addition & 4 deletions src/messages/MessageBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down
32 changes: 32 additions & 0 deletions src/messages/MessageElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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::Username)
, 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)
Expand Down
44 changes: 40 additions & 4 deletions src/messages/MessageElement.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -236,7 +237,6 @@ class TextElement : public MessageElement
protected:
QStringList words_;

private:
MessageColor color_;
FontStyle style_;
};
Expand Down Expand Up @@ -301,6 +301,42 @@ class LinkElement : public TextElement
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
Expand Down
4 changes: 1 addition & 3 deletions src/messages/layouts/MessageLayoutContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -750,9 +750,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_) ||
Expand Down
120 changes: 38 additions & 82 deletions src/providers/twitch/TwitchMessageBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ using namespace chatterino::literals;

namespace {

const QColor AUTOMOD_USER_COLOR{"blue"};

using namespace std::chrono_literals;

const QString regexHelpString("(\\w+)[.,!?;:]*?$");
Expand Down Expand Up @@ -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);
Expand All @@ -767,21 +769,17 @@ void TwitchMessageBuilder::addTextOrEmoji(const QString &string_)
}

auto prefixedUsername = '@' + username;
this->emplace<TextElement>(prefixedUsername,
MessageElementFlag::BoldUsername,
textColor, FontStyle::ChatMediumBold)
->setLink({Link::UserInfo, username})
->setTrailingSpace(false);

this->emplace<TextElement>(prefixedUsername,
MessageElementFlag::NonBoldUsername,
textColor)
auto remainder = string.remove(prefixedUsername);
this->emplace<MentionElement>(prefixedUsername, originalTextColor,
textColor)
->setLink({Link::UserInfo, username})
->setTrailingSpace(false);
->setTrailingSpace(remainder.isEmpty());

this->emplace<TextElement>(string.remove(prefixedUsername),
MessageElementFlag::Text,
originalTextColor);
if (!remainder.isEmpty())
{
this->emplace<TextElement>(remainder, MessageElementFlag::Text,
originalTextColor);
}

return;
}
Expand All @@ -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;
}
Expand Down Expand Up @@ -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())
Expand All @@ -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);
}
Expand Down Expand Up @@ -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())
Expand All @@ -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);
}
Expand Down Expand Up @@ -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: {
Expand Down Expand Up @@ -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 +
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand Down
10 changes: 7 additions & 3 deletions src/singletons/WindowManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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] {
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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;
}

Expand Down