diff --git a/src/singletons/channelmanager.cpp b/src/singletons/channelmanager.cpp index b18a56ff7..8f64f2127 100644 --- a/src/singletons/channelmanager.cpp +++ b/src/singletons/channelmanager.cpp @@ -138,5 +138,12 @@ void ChannelManager::doOnAll(std::function func) func(this->mentionsChannel); } +void ChannelManager::doOnAllNormalChannels(std::function func) +{ + for (const auto &channel : this->twitchChannels) { + func(std::get<0>(channel)); + } +} + } // namespace chatterino } diff --git a/src/singletons/channelmanager.hpp b/src/singletons/channelmanager.hpp index 89e3d257e..24170504a 100644 --- a/src/singletons/channelmanager.hpp +++ b/src/singletons/channelmanager.hpp @@ -26,6 +26,7 @@ public: const std::string &getUserID(const std::string &username); void doOnAll(std::function func); + void doOnAllNormalChannels(std::function func); // Special channels const ChannelPtr whispersChannel; diff --git a/src/singletons/helper/ircmessagehandler.cpp b/src/singletons/helper/ircmessagehandler.cpp index a74e9fda3..4dd477c13 100644 --- a/src/singletons/helper/ircmessagehandler.cpp +++ b/src/singletons/helper/ircmessagehandler.cpp @@ -9,6 +9,7 @@ #include "singletons/resourcemanager.hpp" #include "singletons/windowmanager.hpp" #include "twitch/twitchchannel.hpp" +#include "twitch/twitchmessagebuilder.hpp" using namespace chatterino::messages; @@ -139,7 +140,29 @@ void IrcMessageHandler::handleUserStateMessage(Communi::IrcMessage *message) void IrcMessageHandler::handleWhisperMessage(Communi::IrcMessage *message) { - // TODO: Implement + debug::Log("Received whisper!"); + messages::MessageParseArgs args; + + args.isReceivedWhisper = true; + + auto c = this->channelManager.whispersChannel.get(); + + twitch::TwitchMessageBuilder builder(c, message, message->parameter(1), args); + + if (!builder.isIgnored()) { + messages::MessagePtr _message = builder.build(); + if (_message->flags & messages::Message::Highlighted) { + singletons::ChannelManager::getInstance().mentionsChannel->addMessage(_message); + } + + c->addMessage(_message); + + if (SettingManager::getInstance().inlineWhispers) { + this->channelManager.doOnAllNormalChannels([_message](ChannelPtr channel) { + channel->addMessage(_message); // + }); + } + } } void IrcMessageHandler::handleUserNoticeMessage(Communi::IrcMessage *message) @@ -202,6 +225,7 @@ void IrcMessageHandler::handleWriteConnectionNoticeMessage(Communi::IrcNoticeMes this->handleNoticeMessage(message); } + } // namespace helper } // namespace singletons } // namespace chatterino diff --git a/src/singletons/helper/ircmessagehandler.hpp b/src/singletons/helper/ircmessagehandler.hpp index 81fec9b1e..bbd9ba48a 100644 --- a/src/singletons/helper/ircmessagehandler.hpp +++ b/src/singletons/helper/ircmessagehandler.hpp @@ -27,6 +27,7 @@ public: void handleNoticeMessage(Communi::IrcNoticeMessage *message); void handleWriteConnectionNoticeMessage(Communi::IrcNoticeMessage *message); }; -} -} -} + +} // namespace helper +} // namespace singletons +} // namespace chatterino diff --git a/src/twitch/twitchmessagebuilder.cpp b/src/twitch/twitchmessagebuilder.cpp index 2c67b2963..911831db0 100644 --- a/src/twitch/twitchmessagebuilder.cpp +++ b/src/twitch/twitchmessagebuilder.cpp @@ -1,5 +1,6 @@ #include "twitchmessagebuilder.hpp" #include "debug/log.hpp" +#include "singletons/accountmanager.hpp" #include "singletons/emotemanager.hpp" #include "singletons/ircmanager.hpp" #include "singletons/resourcemanager.hpp" @@ -26,8 +27,22 @@ TwitchMessageBuilder::TwitchMessageBuilder(Channel *_channel, , args(_args) , tags(this->ircMessage->tags()) , usernameColor(singletons::ThemeManager::getInstance().messages.textColors.system) + , originalMessage(_ircMessage->content()) + , action(_ircMessage->isAction()) +{ +} + +TwitchMessageBuilder::TwitchMessageBuilder(Channel *_channel, + const Communi::IrcMessage *_ircMessage, QString content, + const messages::MessageParseArgs &_args) + : channel(_channel) + , twitchChannel(dynamic_cast(_channel)) + , ircMessage(_ircMessage) + , args(_args) + , tags(this->ircMessage->tags()) + , usernameColor(singletons::ThemeManager::getInstance().messages.textColors.system) + , originalMessage(content) { - this->originalMessage = this->ircMessage->content(); } bool TwitchMessageBuilder::isIgnored() const @@ -124,8 +139,8 @@ MessagePtr TwitchMessageBuilder::build() long int i = 0; for (QString split : splits) { - MessageColor textColor = ircMessage->isAction() ? MessageColor(this->usernameColor) - : MessageColor(MessageColor::Text); + MessageColor textColor = + this->action ? MessageColor(this->usernameColor) : MessageColor(MessageColor::Text); // twitch emote if (currentTwitchEmote != twitchEmotes.end() && currentTwitchEmote->first == i) { @@ -243,7 +258,7 @@ void TwitchMessageBuilder::parseUsername() } // username - this->userName = ircMessage->nick(); + this->userName = this->ircMessage->nick(); if (this->userName.isEmpty()) { this->userName = this->tags.value(QLatin1String("login")).toString(); @@ -308,20 +323,36 @@ void TwitchMessageBuilder::appendUsername() if (this->args.isSentWhisper) { // TODO(pajlada): Re-implement // userDisplayString += IrcManager::getInstance().getUser().getUserName(); - } + } else if (this->args.isReceivedWhisper) { + // Sender username + this->emplace(usernameText, MessageElement::Text, this->usernameColor, + FontStyle::MediumBold) + ->setLink({Link::UserInfo, this->userName}); - if (this->args.isReceivedWhisper) { - // TODO(pajlada): Re-implement - // userDisplayString += " -> " + IrcManager::getInstance().getUser().getUserName(); - } + auto currentUser = singletons::AccountManager::getInstance().Twitch.getCurrent(); - if (!ircMessage->isAction()) { - usernameText += ":"; - } + // Separator + this->emplace( + "->", MessageElement::Text, + singletons::ThemeManager::getInstance().messages.textColors.system, FontStyle::Medium); - this->emplace(usernameText, MessageElement::Text, this->usernameColor, - FontStyle::MediumBold) - ->setLink({Link::UserInfo, this->userName}); + QColor selfColor = currentUser->color; + if (!selfColor.isValid()) { + selfColor = singletons::ThemeManager::getInstance().messages.textColors.system; + } + + // Your own username + this->emplace(currentUser->getUserName() + ":", MessageElement::Text, + selfColor, FontStyle::MediumBold); + } else { + if (!this->action) { + usernameText += ":"; + } + + this->emplace(usernameText, MessageElement::Text, this->usernameColor, + FontStyle::MediumBold) + ->setLink({Link::UserInfo, this->userName}); + } } void TwitchMessageBuilder::parseHighlights() @@ -329,11 +360,12 @@ void TwitchMessageBuilder::parseHighlights() static auto player = new QMediaPlayer; static QUrl currentPlayerUrl; singletons::SettingManager &settings = singletons::SettingManager::getInstance(); - static pajlada::Settings::Setting currentUser("/accounts/current"); + auto currentUser = singletons::AccountManager::getInstance().Twitch.getCurrent(); - QString currentUsername = QString::fromStdString(currentUser.getValue()); + QString currentUsername = currentUser->getUserName(); if (this->ircMessage->nick() == currentUsername) { + currentUser->color = this->usernameColor; // Do nothing. Highlights cannot be triggered by yourself return; } @@ -412,7 +444,7 @@ void TwitchMessageBuilder::parseHighlights() } } -void TwitchMessageBuilder::appendTwitchEmote(const Communi::IrcPrivateMessage *ircMessage, +void TwitchMessageBuilder::appendTwitchEmote(const Communi::IrcMessage *ircMessage, const QString &emote, std::vector> &vec) { @@ -441,11 +473,11 @@ void TwitchMessageBuilder::appendTwitchEmote(const Communi::IrcPrivateMessage *i long int start = std::stol(coords.at(0).toStdString(), nullptr, 10); long int end = std::stol(coords.at(1).toStdString(), nullptr, 10); - if (start >= end || start < 0 || end > ircMessage->content().length()) { + if (start >= end || start < 0 || end > this->originalMessage.length()) { return; } - QString name = ircMessage->content().mid(start, end - start + 1); + QString name = this->originalMessage.mid(start, end - start + 1); vec.push_back( std::pair(start, emoteManager.getTwitchEmoteById(id, name))); diff --git a/src/twitch/twitchmessagebuilder.hpp b/src/twitch/twitchmessagebuilder.hpp index 16035a714..9a1696fa4 100644 --- a/src/twitch/twitchmessagebuilder.hpp +++ b/src/twitch/twitchmessagebuilder.hpp @@ -28,10 +28,12 @@ public: explicit TwitchMessageBuilder(Channel *_channel, const Communi::IrcPrivateMessage *_ircMessage, const messages::MessageParseArgs &_args); + explicit TwitchMessageBuilder(Channel *_channel, const Communi::IrcMessage *_ircMessage, + QString content, const messages::MessageParseArgs &_args); Channel *channel; TwitchChannel *twitchChannel; - const Communi::IrcPrivateMessage *ircMessage; + const Communi::IrcMessage *ircMessage; messages::MessageParseArgs args; const QVariantMap tags; @@ -45,7 +47,9 @@ private: QString roomID; QColor usernameColor; - QString originalMessage; + const QString originalMessage; + + const bool action = false; void parseMessageID(); void parseRoomID(); @@ -54,7 +58,7 @@ private: void appendUsername(); void parseHighlights(); - void appendTwitchEmote(const Communi::IrcPrivateMessage *ircMessage, const QString &emote, + void appendTwitchEmote(const Communi::IrcMessage *ircMessage, const QString &emote, std::vector> &vec); bool tryAppendEmote(QString &emoteString); diff --git a/src/twitch/twitchuser.hpp b/src/twitch/twitchuser.hpp index c7562b200..c89f4f30e 100644 --- a/src/twitch/twitchuser.hpp +++ b/src/twitch/twitchuser.hpp @@ -2,6 +2,7 @@ #include "ircaccount.hpp" +#include #include namespace chatterino { @@ -27,6 +28,8 @@ public: bool isAnon() const; + QColor color; + private: QString _oauthClient; QString _oauthToken; diff --git a/src/widgets/settingspages/specialchannelspage.cpp b/src/widgets/settingspages/specialchannelspage.cpp index 6c3685c74..f6df33737 100644 --- a/src/widgets/settingspages/specialchannelspage.cpp +++ b/src/widgets/settingspages/specialchannelspage.cpp @@ -13,6 +13,7 @@ namespace settingspages { SpecialChannelsPage::SpecialChannelsPage() : SettingsPage("Special channels", "") { + singletons::SettingManager &settings = singletons::SettingManager::getInstance(); util::LayoutCreator layoutCreator(this); auto layout = layoutCreator.setLayoutType(); @@ -21,6 +22,12 @@ SpecialChannelsPage::SpecialChannelsPage() mentions.emplace("Join /mentions to view your mentions."); } + auto whispers = layout.emplace("Whispers").setLayoutType(); + { + whispers.emplace("Join /whispers to view your mentions."); + whispers.append(this->createCheckBox("Show whispers inline", settings.inlineWhispers)); + } + layout->addStretch(1); } } // namespace settingspages