diff --git a/CHANGELOG.md b/CHANGELOG.md index 13cc1e73b27..fc5ca5edc0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Major: Added "Channel Filters". See https://wiki.chatterino.com/Filters/ for how they work or how to configure them. (#1748, #2083, #2090, #2200) - Major: Added Streamer Mode configuration (under `Settings -> General`), where you can select which features of Chatterino should behave differently when you are in Streamer Mode. (#2001) +- Major: Color mentions to match the mentioned users. You can disable this by unchecking "Color @usernames" under `Settings -> General -> Advanced (misc.)`. (#1963, #2284) - Minor: Made BetterTTV emote tooltips use authors' display name. (#2267) - Minor: Added Ctrl + 1/2/3/... and Ctrl+9 shortcuts to Emote Popup (activated with Ctrl+E). They work exactly the same as shortcuts in main window. (#2263) - Minor: Added reconnect link to the "You are banned" message. (#2266) diff --git a/src/common/ChannelChatters.cpp b/src/common/ChannelChatters.cpp index ea50bee5856..be5bacb9bf1 100644 --- a/src/common/ChannelChatters.cpp +++ b/src/common/ChannelChatters.cpp @@ -64,9 +64,30 @@ void ChannelChatters::addPartedUser(const QString &user) }); } } + void ChannelChatters::setChatters(UsernameSet &&set) { *this->chatters_.access() = set; } +const QColor ChannelChatters::getUserColor(const QString &user) +{ + const auto chatterColors = this->chatterColors_.access(); + + const auto search = chatterColors->find(user.toLower()); + if (search == chatterColors->end()) + { + // Returns an invalid color so we can decide not to override `textColor` + return QColor(); + } + + return search->second; +} + +void ChannelChatters::setUserColor(const QString &user, const QColor &color) +{ + const auto chatterColors = this->chatterColors_.access(); + chatterColors->insert_or_assign(user.toLower(), color); +} + } // namespace chatterino diff --git a/src/common/ChannelChatters.hpp b/src/common/ChannelChatters.hpp index 2aba51da821..a65dfe0d695 100644 --- a/src/common/ChannelChatters.hpp +++ b/src/common/ChannelChatters.hpp @@ -18,12 +18,15 @@ class ChannelChatters void addJoinedUser(const QString &user); void addPartedUser(const QString &user); void setChatters(UsernameSet &&set); + const QColor getUserColor(const QString &user); + void setUserColor(const QString &user, const QColor &color); private: Channel &channel_; // maps 2 char prefix to set of names UniqueAccess chatters_; + UniqueAccess> chatterColors_; // combines multiple joins/parts into one message UniqueAccess joinedUsers_; diff --git a/src/providers/twitch/TwitchMessageBuilder.cpp b/src/providers/twitch/TwitchMessageBuilder.cpp index 000243f35fb..5629ffcafea 100644 --- a/src/providers/twitch/TwitchMessageBuilder.cpp +++ b/src/providers/twitch/TwitchMessageBuilder.cpp @@ -480,6 +480,16 @@ void TwitchMessageBuilder::addTextOrEmoji(const QString &string_) { QString username = match.captured(1); + if (getSettings()->colorUsernames) + { + if (auto userColor = + this->twitchChannel->getUserColor(username); + userColor.isValid()) + { + textColor = userColor; + } + } + this->emplace(string, MessageElementFlag::BoldUsername, textColor, FontStyle::ChatMediumBold) ->setLink({Link::UserInfo, username}); @@ -499,6 +509,16 @@ void TwitchMessageBuilder::addTextOrEmoji(const QString &string_) if (match.hasMatch() && chatters->contains(username)) { + if (getSettings()->colorUsernames) + { + if (auto userColor = + this->twitchChannel->getUserColor(username); + userColor.isValid()) + { + textColor = userColor; + } + } + this->emplace(string, MessageElementFlag::BoldUsername, textColor, FontStyle::ChatMediumBold) ->setLink({Link::UserInfo, username}); @@ -580,6 +600,7 @@ void TwitchMessageBuilder::parseUsername() // } this->message().loginName = this->userName; + this->twitchChannel->setUserColor(this->userName, this->usernameColor_); // Update current user color if this is our message auto currentUser = getApp()->accounts->twitch.getCurrent(); diff --git a/src/singletons/Settings.hpp b/src/singletons/Settings.hpp index 86527fd5e8d..72214a1c313 100644 --- a/src/singletons/Settings.hpp +++ b/src/singletons/Settings.hpp @@ -104,6 +104,7 @@ class Settings : public ABSettings, public ConcurrentSettings BoolSetting enableSmoothScrollingNewMessages = { "/appearance/smoothScrollingNewMessages", false}; BoolSetting boldUsernames = {"/appearance/messages/boldUsernames", true}; + BoolSetting colorUsernames = {"/appearance/messages/colorUsernames", true}; BoolSetting findAllUsernames = {"/appearance/messages/findAllUsernames", false}; // BoolSetting customizable splitheader diff --git a/src/widgets/settingspages/GeneralPage.cpp b/src/widgets/settingspages/GeneralPage.cpp index f80830fbf92..c1fb0bf2bc1 100644 --- a/src/widgets/settingspages/GeneralPage.cpp +++ b/src/widgets/settingspages/GeneralPage.cpp @@ -572,6 +572,7 @@ void GeneralPage::initLayout(GeneralPageView &layout) s.autoCloseUserPopup); layout.addCheckbox("Lowercase domains (anti-phishing)", s.lowercaseDomains); layout.addCheckbox("Bold @usernames", s.boldUsernames); + layout.addCheckbox("Color @usernames", s.colorUsernames); layout.addCheckbox("Try to find usernames without @ prefix", s.findAllUsernames); layout.addDropdown(