fix: Display Sent IRC Messages Like Received Ones (#4027)

This commit is contained in:
nerix
2022-10-01 17:36:22 +02:00
committed by GitHub
parent a275a1793a
commit ba586f01d0
8 changed files with 230 additions and 186 deletions
+166
View File
@@ -1,6 +1,7 @@
#include "MessageBuilder.hpp"
#include "Application.hpp"
#include "common/IrcColors.hpp"
#include "common/LinkParser.hpp"
#include "controllers/accounts/AccountController.hpp"
#include "messages/Image.hpp"
@@ -16,6 +17,14 @@
#include <QDateTime>
namespace {
QRegularExpression IRC_COLOR_PARSE_REGEX(
"(\u0003(\\d{1,2})?(,(\\d{1,2}))?|\u000f)",
QRegularExpression::UseUnicodePropertiesOption);
} // namespace
namespace chatterino {
MessagePtr makeSystemMessage(const QString &text)
@@ -579,6 +588,163 @@ void MessageBuilder::addLink(const QString &origLink,
});
}
void MessageBuilder::addIrcMessageText(const QString &text)
{
this->message().messageText = text;
auto words = text.split(' ');
MessageColor defaultColorType = MessageColor::Text;
const auto &defaultColor = defaultColorType.getColor(*getApp()->themes);
QColor textColor = defaultColor;
int fg = -1;
int bg = -1;
for (const 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())
{
this->addIrcWord(string, textColor);
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;
}
this->addIrcWord(
string.mid(lastPos, match.capturedStart() - lastPos),
textColor, false);
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;
}
this->addIrcWord(string.mid(lastPos), textColor);
}
this->message().elements.back()->setTrailingSpace(false);
}
void MessageBuilder::addTextOrEmoji(EmotePtr emote)
{
this->emplace<EmoteElement>(emote, MessageElementFlag::EmojiAll);
}
void MessageBuilder::addTextOrEmoji(const QString &string_)
{
auto string = QString(string_);
// Actually just text
auto linkString = this->matchLink(string);
auto link = Link();
auto &&textColor = this->textColor_;
if (linkString.isEmpty())
{
if (string.startsWith('@'))
{
this->emplace<TextElement>(string, MessageElementFlag::BoldUsername,
textColor, FontStyle::ChatMediumBold);
this->emplace<TextElement>(
string, MessageElementFlag::NonBoldUsername, textColor);
}
else
{
this->emplace<TextElement>(string, MessageElementFlag::Text,
textColor);
}
}
else
{
this->addLink(string, linkString);
}
}
void MessageBuilder::addIrcWord(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);
}
}
}
TextElement *MessageBuilder::emplaceSystemTextAndUpdate(const QString &text,
QString &toUpdate)
{