From 40664686edd2c3c7d877501f0bf83507d3fb349e Mon Sep 17 00:00:00 2001 From: Rasmus Karlsson Date: Sat, 6 Apr 2024 12:52:51 +0200 Subject: [PATCH 1/4] fix: update color of usernames & boldness of usernames on the fly Boldness was already covered before :) --- src/messages/MessageBuilder.cpp | 5 +- src/messages/MessageElement.cpp | 32 +++++ src/messages/MessageElement.hpp | 44 ++++++- .../layouts/MessageLayoutContainer.cpp | 4 +- src/providers/twitch/TwitchMessageBuilder.cpp | 120 ++++++------------ src/singletons/WindowManager.cpp | 10 +- 6 files changed, 119 insertions(+), 96 deletions(-) diff --git a/src/messages/MessageBuilder.cpp b/src/messages/MessageBuilder.cpp index cc71558f65e..dbf8cacca75 100644 --- a/src/messages/MessageBuilder.cpp +++ b/src/messages/MessageBuilder.cpp @@ -764,10 +764,7 @@ void MessageBuilder::addTextOrEmoji(const QString &string_) auto &&textColor = this->textColor_; if (string.startsWith('@')) { - this->emplace(string, MessageElementFlag::BoldUsername, - textColor, FontStyle::ChatMediumBold); - this->emplace(string, MessageElementFlag::NonBoldUsername, - textColor); + this->emplace(string, textColor, textColor); } else { diff --git a/src/messages/MessageElement.cpp b/src/messages/MessageElement.cpp index 56d1e2ed3d3..30b1123b59a 100644 --- a/src/messages/MessageElement.cpp +++ b/src/messages/MessageElement.cpp @@ -702,6 +702,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) diff --git a/src/messages/MessageElement.hpp b/src/messages/MessageElement.hpp index 68f90e9b57e..b4df619aca1 100644 --- a/src/messages/MessageElement.hpp +++ b/src/messages/MessageElement.hpp @@ -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 @@ class TextElement : public MessageElement protected: QStringList words_; -private: MessageColor color_; FontStyle style_; }; @@ -298,6 +298,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 diff --git a/src/messages/layouts/MessageLayoutContainer.cpp b/src/messages/layouts/MessageLayoutContainer.cpp index 29d70e0a193..1fad671f275 100644 --- a/src/messages/layouts/MessageLayoutContainer.cpp +++ b/src/messages/layouts/MessageLayoutContainer.cpp @@ -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_) || diff --git a/src/providers/twitch/TwitchMessageBuilder.cpp b/src/providers/twitch/TwitchMessageBuilder.cpp index 524d0375de5..2177d2f5bc4 100644 --- a/src/providers/twitch/TwitchMessageBuilder.cpp +++ b/src/providers/twitch/TwitchMessageBuilder.cpp @@ -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(prefixedUsername, - MessageElementFlag::BoldUsername, - textColor, FontStyle::ChatMediumBold) - ->setLink({Link::UserInfo, username}) - ->setTrailingSpace(false); - - this->emplace(prefixedUsername, - MessageElementFlag::NonBoldUsername, - textColor) + auto remainder = string.remove(prefixedUsername); + this->emplace(prefixedUsername, originalTextColor, + textColor) ->setLink({Link::UserInfo, username}) - ->setTrailingSpace(false); + ->setTrailingSpace(remainder.isEmpty()); - this->emplace(string.remove(prefixedUsername), - MessageElementFlag::Text, - originalTextColor); + if (!remainder.isEmpty()) + { + this->emplace(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(username, - MessageElementFlag::BoldUsername, - textColor, FontStyle::ChatMediumBold) + auto remainder = string.remove(username); + this->emplace(username, originalTextColor, + textColor) ->setLink({Link::UserInfo, username}) - ->setTrailingSpace(false); + ->setTrailingSpace(remainder.isEmpty()); - this->emplace( - username, MessageElementFlag::NonBoldUsername, textColor) - ->setLink({Link::UserInfo, username}) - ->setTrailingSpace(false); - - this->emplace(string.remove(username), - MessageElementFlag::Text, - originalTextColor); + if (!remainder.isEmpty()) + { + this->emplace(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(username, MessageElementFlag::BoldUsername, - color, FontStyle::ChatMediumBold) - ->setLink({Link::UserInfo, username}) - ->setTrailingSpace(false); - builder - ->emplace(username, - MessageElementFlag::NonBoldUsername, color) + builder->emplace(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(user.userName, - MessageElementFlag::BoldUsername, color, - FontStyle::ChatMediumBold) - ->setLink({Link::UserInfo, user.userLogin}) - ->setTrailingSpace(false); - builder - ->emplace(user.userName, - MessageElementFlag::NonBoldUsername, color) + ->emplace(user.userName, MessageColor::System, + color) ->setLink({Link::UserInfo, user.userLogin}) ->setTrailingSpace(false); } @@ -1960,12 +1938,8 @@ MessagePtr TwitchMessageBuilder::makeAutomodInfoMessage( builder.emplace(makeAutoModBadge(), MessageElementFlag::BadgeChannelAuthority); // AutoMod "username" - builder.emplace("AutoMod:", MessageElementFlag::BoldUsername, - MessageColor(QColor("blue")), - FontStyle::ChatMediumBold); - builder.emplace( - "AutoMod:", MessageElementFlag::NonBoldUsername, - MessageColor(QColor("blue"))); + builder.emplace("AutoMod:", MessageColor::Text, + AUTOMOD_USER_COLOR); switch (action.type) { case AutomodInfoAction::OnHold: { @@ -2019,12 +1993,8 @@ std::pair TwitchMessageBuilder::makeAutomodMessage( builder.emplace(makeAutoModBadge(), MessageElementFlag::BadgeChannelAuthority); // AutoMod "username" - builder.emplace("AutoMod:", MessageElementFlag::BoldUsername, - MessageColor(QColor("blue")), - FontStyle::ChatMediumBold); - builder.emplace( - "AutoMod:", MessageElementFlag::NonBoldUsername, - MessageColor(QColor("blue"))); + builder2.emplace("AutoMod:", MessageColor::Text, + AUTOMOD_USER_COLOR); // AutoMod header message builder.emplace( ("Held a message for reason: " + action.reason + @@ -2072,14 +2042,8 @@ std::pair TwitchMessageBuilder::makeAutomodMessage( // sender username builder2 - .emplace( - action.target.displayName + ":", MessageElementFlag::BoldUsername, - MessageColor(action.target.color), FontStyle::ChatMediumBold) - ->setLink({Link::UserInfo, action.target.login}); - builder2 - .emplace(action.target.displayName + ":", - MessageElementFlag::NonBoldUsername, - MessageColor(action.target.color)) + .emplace(action.target.displayName + ":", + MessageColor::Text, action.target.color) ->setLink({Link::UserInfo, action.target.login}); // sender's message caught by AutoMod builder2.emplace(action.message, MessageElementFlag::Text, @@ -2275,17 +2239,9 @@ std::pair TwitchMessageBuilder::makeLowTrustUserMessage( appendBadges(&builder2, action.senderBadges, {}, twitchChannel); // sender username - builder2 - .emplace(action.suspiciousUserDisplayName + ":", - MessageElementFlag::BoldUsername, - MessageColor(action.suspiciousUserColor), - FontStyle::ChatMediumBold) - ->setLink({Link::UserInfo, action.suspiciousUserLogin}); - builder2 - .emplace(action.suspiciousUserDisplayName + ":", - MessageElementFlag::NonBoldUsername, - MessageColor(action.suspiciousUserColor)) - ->setLink({Link::UserInfo, action.suspiciousUserLogin}); + builder2.emplace(action.suspiciousUserDisplayName + ":", + MessageColor::Text, + action.suspiciousUserColor); // sender's message caught by AutoMod for (const auto &fragment : action.fragments) diff --git a/src/singletons/WindowManager.cpp b/src/singletons/WindowManager.cpp index 56bea50ae69..63bc63b366b 100644 --- a/src/singletons/WindowManager.cpp +++ b/src/singletons/WindowManager.cpp @@ -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; } From 77538856ceb73e917f76c5b7cc94c71dc829ed40 Mon Sep 17 00:00:00 2001 From: Rasmus Karlsson Date: Sun, 12 May 2024 13:21:20 +0200 Subject: [PATCH 2/4] Disabled "Color usernames" no longer removes automod color --- src/providers/twitch/TwitchMessageBuilder.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/providers/twitch/TwitchMessageBuilder.cpp b/src/providers/twitch/TwitchMessageBuilder.cpp index 2177d2f5bc4..3dfd39720ec 100644 --- a/src/providers/twitch/TwitchMessageBuilder.cpp +++ b/src/providers/twitch/TwitchMessageBuilder.cpp @@ -1938,7 +1938,7 @@ MessagePtr TwitchMessageBuilder::makeAutomodInfoMessage( builder.emplace(makeAutoModBadge(), MessageElementFlag::BadgeChannelAuthority); // AutoMod "username" - builder.emplace("AutoMod:", MessageColor::Text, + builder.emplace("AutoMod:", AUTOMOD_USER_COLOR, AUTOMOD_USER_COLOR); switch (action.type) { @@ -1993,7 +1993,7 @@ std::pair TwitchMessageBuilder::makeAutomodMessage( builder.emplace(makeAutoModBadge(), MessageElementFlag::BadgeChannelAuthority); // AutoMod "username" - builder2.emplace("AutoMod:", MessageColor::Text, + builder2.emplace("AutoMod:", AUTOMOD_USER_COLOR, AUTOMOD_USER_COLOR); // AutoMod header message builder.emplace( From 513c6b373978384a605e9f6ccf6ee994164d52ea Mon Sep 17 00:00:00 2001 From: Rasmus Karlsson Date: Sun, 12 May 2024 13:23:28 +0200 Subject: [PATCH 3/4] Add changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea438bd6136..e86d208c361 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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) From 796c9721df2a1589d0f37b117c5d907c4fd00916 Mon Sep 17 00:00:00 2001 From: Rasmus Karlsson Date: Sun, 12 May 2024 14:10:47 +0200 Subject: [PATCH 4/4] fix: mark the mention element with the Text + Mention flags This ensures it's included in other text-like things, and not excluded --- src/messages/MessageElement.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/messages/MessageElement.cpp b/src/messages/MessageElement.cpp index 172a08b5109..b79a2183c45 100644 --- a/src/messages/MessageElement.cpp +++ b/src/messages/MessageElement.cpp @@ -705,7 +705,7 @@ Link LinkElement::getLink() const MentionElement::MentionElement(const QString &name, MessageColor fallbackColor_, MessageColor userColor_) - : TextElement(name, MessageElementFlag::Username) + : TextElement(name, {MessageElementFlag::Text, MessageElementFlag::Mention}) , fallbackColor(fallbackColor_) , userColor(userColor_) {