2020-07-04 15:15:59 +02:00
|
|
|
#include "providers/irc/IrcMessageBuilder.hpp"
|
|
|
|
|
|
|
|
#include "Application.hpp"
|
2021-11-07 14:55:43 +01:00
|
|
|
#include "common/IrcColors.hpp"
|
2020-07-04 15:15:59 +02:00
|
|
|
#include "controllers/accounts/AccountController.hpp"
|
|
|
|
#include "controllers/ignores/IgnoreController.hpp"
|
|
|
|
#include "controllers/ignores/IgnorePhrase.hpp"
|
|
|
|
#include "messages/Message.hpp"
|
|
|
|
#include "providers/chatterino/ChatterinoBadges.hpp"
|
|
|
|
#include "singletons/Emotes.hpp"
|
|
|
|
#include "singletons/Resources.hpp"
|
|
|
|
#include "singletons/Settings.hpp"
|
|
|
|
#include "singletons/Theme.hpp"
|
|
|
|
#include "singletons/WindowManager.hpp"
|
2021-08-29 13:35:19 +02:00
|
|
|
#include "util/Helpers.hpp"
|
2020-07-04 15:15:59 +02:00
|
|
|
#include "util/IrcHelpers.hpp"
|
|
|
|
#include "widgets/Window.hpp"
|
|
|
|
|
2021-11-07 14:55:43 +01:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
QRegularExpression IRC_COLOR_PARSE_REGEX(
|
|
|
|
"(\u0003(\\d{1,2})?(,(\\d{1,2}))?|\u000f)",
|
|
|
|
QRegularExpression::UseUnicodePropertiesOption);
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
2020-07-04 15:15:59 +02:00
|
|
|
namespace chatterino {
|
|
|
|
|
|
|
|
IrcMessageBuilder::IrcMessageBuilder(
|
|
|
|
Channel *_channel, const Communi::IrcPrivateMessage *_ircMessage,
|
|
|
|
const MessageParseArgs &_args)
|
|
|
|
: SharedMessageBuilder(_channel, _ircMessage, _args)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
IrcMessageBuilder::IrcMessageBuilder(Channel *_channel,
|
|
|
|
const Communi::IrcMessage *_ircMessage,
|
|
|
|
const MessageParseArgs &_args,
|
|
|
|
QString content, bool isAction)
|
|
|
|
: SharedMessageBuilder(_channel, _ircMessage, _args, content, isAction)
|
|
|
|
{
|
|
|
|
assert(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
MessagePtr IrcMessageBuilder::build()
|
|
|
|
{
|
|
|
|
// PARSE
|
|
|
|
this->parse();
|
2021-08-29 13:35:19 +02:00
|
|
|
this->usernameColor_ = getRandomColor(this->ircMessage->nick());
|
2020-07-04 15:15:59 +02:00
|
|
|
|
|
|
|
// PUSH ELEMENTS
|
|
|
|
this->appendChannelName();
|
|
|
|
|
2021-07-17 18:22:25 +02:00
|
|
|
this->emplace<TimestampElement>(
|
|
|
|
calculateMessageTimestamp(this->ircMessage));
|
2020-07-04 15:15:59 +02:00
|
|
|
|
|
|
|
this->appendUsername();
|
|
|
|
|
|
|
|
// words
|
|
|
|
this->addWords(this->originalMessage_.split(' '));
|
|
|
|
|
|
|
|
this->message().messageText = this->originalMessage_;
|
|
|
|
this->message().searchText = this->message().localizedName + " " +
|
|
|
|
this->userName + ": " + this->originalMessage_;
|
|
|
|
|
|
|
|
// highlights
|
|
|
|
this->parseHighlights();
|
|
|
|
|
|
|
|
// highlighting incoming whispers if requested per setting
|
|
|
|
if (this->args.isReceivedWhisper && getSettings()->highlightInlineWhispers)
|
|
|
|
{
|
|
|
|
this->message().flags.set(MessageFlag::HighlightedWhisper, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
return this->release();
|
|
|
|
}
|
|
|
|
|
|
|
|
void IrcMessageBuilder::addWords(const QStringList &words)
|
|
|
|
{
|
2021-11-07 20:58:22 +01:00
|
|
|
MessageColor defaultColorType = this->textColor_;
|
2021-11-07 14:55:43 +01:00
|
|
|
auto defaultColor = defaultColorType.getColor(*getApp()->themes);
|
|
|
|
QColor textColor = defaultColor;
|
|
|
|
int fg = -1;
|
|
|
|
int bg = -1;
|
|
|
|
|
|
|
|
for (auto word : words)
|
|
|
|
{
|
|
|
|
if (word.isEmpty())
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto string = QString(word);
|
|
|
|
|
|
|
|
// Actually just text
|
|
|
|
auto linkString = this->matchLink(string);
|
|
|
|
auto link = Link();
|
|
|
|
|
|
|
|
if (!linkString.isEmpty())
|
|
|
|
{
|
|
|
|
this->addLink(string, linkString);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Does the word contain a color changer? If so, split on it.
|
|
|
|
// Add color indicators, then combine into the same word with the color being changed
|
|
|
|
|
|
|
|
auto i = IRC_COLOR_PARSE_REGEX.globalMatch(string);
|
|
|
|
|
|
|
|
if (!i.hasNext())
|
|
|
|
{
|
2021-11-20 12:18:40 +01:00
|
|
|
this->addText(string, textColor);
|
2021-11-07 14:55:43 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
int lastPos = 0;
|
|
|
|
|
|
|
|
while (i.hasNext())
|
|
|
|
{
|
|
|
|
auto match = i.next();
|
|
|
|
|
|
|
|
if (lastPos != match.capturedStart() && match.capturedStart() != 0)
|
|
|
|
{
|
|
|
|
if (fg >= 0 && fg <= 98)
|
|
|
|
{
|
|
|
|
textColor = IRC_COLORS[fg];
|
|
|
|
getApp()->themes->normalizeColor(textColor);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
textColor = defaultColor;
|
|
|
|
}
|
2021-11-20 12:18:40 +01:00
|
|
|
this->addText(
|
|
|
|
string.mid(lastPos, match.capturedStart() - lastPos),
|
|
|
|
textColor, false);
|
2021-11-07 14:55:43 +01:00
|
|
|
lastPos = match.capturedStart() + match.capturedLength();
|
|
|
|
}
|
|
|
|
if (!match.captured(1).isEmpty())
|
|
|
|
{
|
|
|
|
fg = -1;
|
|
|
|
bg = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!match.captured(2).isEmpty())
|
|
|
|
{
|
|
|
|
fg = match.captured(2).toInt(nullptr);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
fg = -1;
|
|
|
|
}
|
|
|
|
if (!match.captured(4).isEmpty())
|
|
|
|
{
|
|
|
|
bg = match.captured(4).toInt(nullptr);
|
|
|
|
}
|
|
|
|
else if (fg == -1)
|
|
|
|
{
|
|
|
|
bg = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
lastPos = match.capturedStart() + match.capturedLength();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fg >= 0 && fg <= 98)
|
|
|
|
{
|
|
|
|
textColor = IRC_COLORS[fg];
|
|
|
|
getApp()->themes->normalizeColor(textColor);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
textColor = defaultColor;
|
|
|
|
}
|
2021-11-20 12:18:40 +01:00
|
|
|
this->addText(string.mid(lastPos), textColor);
|
2021-11-07 14:55:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
this->message().elements.back()->setTrailingSpace(false);
|
2020-07-04 15:15:59 +02:00
|
|
|
}
|
|
|
|
|
2021-11-20 12:18:40 +01:00
|
|
|
void IrcMessageBuilder::addText(const QString &text, const QColor &color,
|
|
|
|
bool addSpace)
|
|
|
|
{
|
|
|
|
this->textColor_ = color;
|
|
|
|
for (auto &variant : getApp()->emotes->emojis.parse(text))
|
|
|
|
{
|
|
|
|
boost::apply_visitor(
|
|
|
|
[&](auto &&arg) {
|
|
|
|
this->addTextOrEmoji(arg);
|
|
|
|
},
|
|
|
|
variant);
|
|
|
|
if (!addSpace)
|
|
|
|
{
|
|
|
|
this->message().elements.back()->setTrailingSpace(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-04 15:15:59 +02:00
|
|
|
void IrcMessageBuilder::appendUsername()
|
|
|
|
{
|
|
|
|
QString username = this->userName;
|
|
|
|
this->message().loginName = username;
|
2021-07-08 17:26:34 +02:00
|
|
|
this->message().displayName = username;
|
2020-07-04 15:15:59 +02:00
|
|
|
|
|
|
|
// The full string that will be rendered in the chat widget
|
|
|
|
QString usernameText = username;
|
|
|
|
|
|
|
|
if (!this->action_)
|
|
|
|
{
|
|
|
|
usernameText += ":";
|
|
|
|
}
|
|
|
|
|
|
|
|
this->emplace<TextElement>(usernameText, MessageElementFlag::Username,
|
|
|
|
this->usernameColor_, FontStyle::ChatMediumBold)
|
2021-07-08 17:26:34 +02:00
|
|
|
->setLink({Link::UserInfo, this->message().loginName});
|
2020-07-04 15:15:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace chatterino
|