Skip to content

Commit

Permalink
refactor: merge adjecent words into one TextElement (#5847)
Browse files Browse the repository at this point in the history
  • Loading branch information
Nerixyz authored Jan 22, 2025
1 parent ea02a42 commit 0a3cc1d
Show file tree
Hide file tree
Showing 42 changed files with 289 additions and 2,719 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
- Dev: Updated Conan dependencies. (#5776)
- Dev: Replaced usage of `parseTime` with `serverReceivedTime` for clearchat messages. (#5824)
- Dev: Support Boost 1.87. (#5832)
- Dev: Words from `TextElement`s are now combined where possible. (#5847)

## 2.5.2

Expand Down
68 changes: 49 additions & 19 deletions src/messages/MessageBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -526,8 +526,7 @@ MessageBuilder::MessageBuilder(SystemMessageTag, const QString &text,
continue;
}

this->emplace<TextElement>(word, MessageElementFlag::Text,
MessageColor::System);
this->appendOrEmplaceText(word, MessageColor::System);
}
this->message().flags.set(MessageFlag::System);
this->message().flags.set(MessageFlag::DoNotTriggerNotification);
Expand All @@ -552,8 +551,7 @@ MessagePtrMut MessageBuilder::makeSystemMessageWithUser(
continue;
}

builder.emplace<TextElement>(word, MessageElementFlag::Text,
MessageColor::System);
builder.appendOrEmplaceText(word, MessageColor::System);
}

builder->flags.set(MessageFlag::System);
Expand Down Expand Up @@ -619,8 +617,7 @@ MessagePtrMut MessageBuilder::makeSubgiftMessage(const QString &text,
continue;
}

builder.emplace<TextElement>(word, MessageElementFlag::Text,
MessageColor::System);
builder.appendOrEmplaceText(word, MessageColor::System);
}

builder->flags.set(MessageFlag::System);
Expand Down Expand Up @@ -743,18 +740,18 @@ MessageBuilder::MessageBuilder(const BanAction &action, uint32_t count)
this->emplaceSystemTextAndUpdate("were", text);
if (action.isBan())
{
this->emplaceSystemTextAndUpdate("banned", text);
this->appendOrEmplaceSystemTextAndUpdate("banned", text);
}
else
{
this->emplaceSystemTextAndUpdate(
this->appendOrEmplaceSystemTextAndUpdate(
QString("timed out for %1").arg(formatTime(action.duration)),
text);
}

if (!action.source.login.isEmpty())
{
this->emplaceSystemTextAndUpdate("by", text);
this->appendOrEmplaceSystemTextAndUpdate("by", text);
this->emplaceSystemTextAndUpdate(
action.source.login + (action.reason.isEmpty() ? "." : ":"),
text)
Expand All @@ -763,7 +760,7 @@ MessageBuilder::MessageBuilder(const BanAction &action, uint32_t count)

if (!action.reason.isEmpty())
{
this->emplaceSystemTextAndUpdate(
this->appendOrEmplaceSystemTextAndUpdate(
QString("\"%1\".").arg(action.reason), text);
}
}
Expand Down Expand Up @@ -812,7 +809,7 @@ MessageBuilder::MessageBuilder(const BanAction &action, uint32_t count)

if (count > 1)
{
this->emplaceSystemTextAndUpdate(
this->appendOrEmplaceSystemTextAndUpdate(
QString("(%1 times)").arg(count), text);
}
}
Expand Down Expand Up @@ -1226,6 +1223,42 @@ bool MessageBuilder::isIgnored(const QString &originalMessage,
});
}

void MessageBuilder::appendOrEmplaceText(const QString &text,
MessageColor color)
{
auto fallback = [&] {
this->emplace<TextElement>(text, MessageElementFlag::Text, color);
};
if (this->message_->elements.empty())
{
fallback();
return;
}

auto *back =
dynamic_cast<TextElement *>(this->message_->elements.back().get());
if (!back || //
dynamic_cast<MentionElement *>(back) || //
dynamic_cast<LinkElement *>(back) || //
!back->hasTrailingSpace() || //
back->getFlags() != MessageElementFlag::Text || //
back->color() != color)
{
fallback();
return;
}

back->appendText(text);
}

void MessageBuilder::appendOrEmplaceSystemTextAndUpdate(const QString &text,
QString &toUpdate)
{
toUpdate.append(text);
toUpdate.append(' ');
this->appendOrEmplaceText(text, MessageColor::System);
}

void MessageBuilder::triggerHighlights(const Channel *channel,
const HighlightAlert &alert)
{
Expand Down Expand Up @@ -1759,22 +1792,19 @@ MessagePtr MessageBuilder::makeAutomodInfoMessage(
QString info("Hey! Your message is being checked "
"by mods and has not been sent.");
text += info;
builder.emplace<TextElement>(info, MessageElementFlag::Text,
MessageColor::Text);
builder.appendOrEmplaceText(info, MessageColor::Text);
}
break;
case AutomodInfoAction::Denied: {
QString info("Mods have removed your message.");
text += info;
builder.emplace<TextElement>(info, MessageElementFlag::Text,
MessageColor::Text);
builder.appendOrEmplaceText(info, MessageColor::Text);
}
break;
case AutomodInfoAction::Approved: {
QString info("Mods have accepted your message.");
text += info;
builder.emplace<TextElement>(info, MessageElementFlag::Text,
MessageColor::Text);
builder.appendOrEmplaceText(info, MessageColor::Text);
}
break;
}
Expand Down Expand Up @@ -2019,7 +2049,7 @@ MessagePtrMut MessageBuilder::makeClearChatMessage(const QDateTime &now,

if (count > 1)
{
builder.emplaceSystemTextAndUpdate(
builder.appendOrEmplaceSystemTextAndUpdate(
'(' % QString::number(count) % u" times)", messageText);
}

Expand Down Expand Up @@ -2332,7 +2362,7 @@ void MessageBuilder::addTextOrEmote(TextState &state, QString string)
}
}

this->emplace<TextElement>(string, MessageElementFlag::Text, textColor);
this->appendOrEmplaceText(string, textColor);
}

bool MessageBuilder::isEmpty() const
Expand Down
4 changes: 4 additions & 0 deletions src/messages/MessageBuilder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ class MessageBuilder
return pointer;
}

void appendOrEmplaceText(const QString &text, MessageColor color);
void appendOrEmplaceSystemTextAndUpdate(const QString &text,
QString &toUpdate);

static void triggerHighlights(const Channel *channel,
const HighlightAlert &alert);

Expand Down
6 changes: 6 additions & 0 deletions src/messages/MessageColor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ struct MessageColor {

QString toString() const;

bool operator==(const MessageColor &other) const noexcept
{
return this->type_ == other.type_ &&
this->customColor_ == other.customColor_;
}

private:
Type type_;
QColor customColor_;
Expand Down
43 changes: 43 additions & 0 deletions src/messages/MessageElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,49 @@ void TextElement::addToContainer(MessageLayoutContainer &container,
}
}

const MessageColor &TextElement::color() const noexcept
{
return this->color_;
}

FontStyle TextElement::fontStyle() const noexcept
{
return this->style_;
}

void TextElement::appendText(QStringView text)
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
for (auto word : text.split(' ')) // creates a QList
#else
for (auto word : text.tokenize(u' '))
#endif
{
this->words_.append(word.toString());
}
}

void TextElement::appendText(const QString &text)
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
this->appendText(QStringView{text});
#else
qsizetype firstSpace = text.indexOf(u' ');
if (firstSpace == -1)
{
// reuse (ref) `text`
this->words_.emplace_back(text);
return;
}

this->words_.emplace_back(text.sliced(0, firstSpace));
for (auto word : QStringView{text}.sliced(firstSpace + 1).tokenize(u' '))
{
this->words_.emplace_back(word.toString());
}
#endif
}

QJsonObject TextElement::toJson() const
{
auto base = MessageElement::toJson();
Expand Down
6 changes: 6 additions & 0 deletions src/messages/MessageElement.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,12 @@ class TextElement : public MessageElement

QJsonObject toJson() const override;

const MessageColor &color() const noexcept;
FontStyle fontStyle() const noexcept;

void appendText(QStringView text);
void appendText(const QString &text);

protected:
QStringList words_;

Expand Down
16 changes: 1 addition & 15 deletions tests/snapshots/IrcMessageHandler/all-usernames.json
Original file line number Diff line number Diff line change
Expand Up @@ -178,21 +178,7 @@
"trailingSpace": true,
"type": "TextElement",
"words": [
"!"
]
},
{
"color": "Text",
"flags": "Text",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "",
"trailingSpace": true,
"type": "TextElement",
"words": [
"!",
"UserColorKappa"
]
},
Expand Down
32 changes: 2 additions & 30 deletions tests/snapshots/IrcMessageHandler/announcement.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,36 +132,8 @@
"trailingSpace": true,
"type": "TextElement",
"words": [
"mm"
]
},
{
"color": "Text",
"flags": "Text",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "",
"trailingSpace": true,
"type": "TextElement",
"words": [
"test"
]
},
{
"color": "Text",
"flags": "Text",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "",
"trailingSpace": true,
"type": "TextElement",
"words": [
"mm",
"test",
"lol"
]
},
Expand Down
16 changes: 1 addition & 15 deletions tests/snapshots/IrcMessageHandler/bad-emotes3.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,21 +89,7 @@
"trailingSpace": true,
"type": "TextElement",
"words": [
"foo"
]
},
{
"color": "Text",
"flags": "Text",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "",
"trailingSpace": true,
"type": "TextElement",
"words": [
"foo",
"bar"
]
},
Expand Down
16 changes: 1 addition & 15 deletions tests/snapshots/IrcMessageHandler/bad-emotes4.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,21 +89,7 @@
"trailingSpace": true,
"type": "TextElement",
"words": [
"foo"
]
},
{
"color": "Text",
"flags": "Text",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "",
"trailingSpace": true,
"type": "TextElement",
"words": [
"foo",
"bar"
]
},
Expand Down
Loading

0 comments on commit 0a3cc1d

Please sign in to comment.