refactor: decouple reply parsing from MessageBuilder (#5660)

This commit is contained in:
nerix 2024-10-19 14:04:44 +02:00 committed by GitHub
parent 43bea0f042
commit 5c9b17c31a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 58 additions and 34 deletions

View file

@ -109,6 +109,7 @@
- Dev: `GIFTimer` is no longer initialized in tests. (#5608) - Dev: `GIFTimer` is no longer initialized in tests. (#5608)
- Dev: Emojis now use flags instead of a set of strings for capabilities. (#5616) - Dev: Emojis now use flags instead of a set of strings for capabilities. (#5616)
- Dev: Refactored static `MessageBuilder` helpers to standalone functions. (#5652) - Dev: Refactored static `MessageBuilder` helpers to standalone functions. (#5652)
- Dev: Decoupled reply parsing from `MessageBuilder`. (#5660)
## 2.5.1 ## 2.5.1

View file

@ -123,24 +123,21 @@ int stripLeadingReplyMention(const QVariantMap &tags, QString &content)
return 0; return 0;
} }
void updateReplyParticipatedStatus(const QVariantMap &tags, [[nodiscard]] bool shouldHighlightReplyThread(
const QString &senderLogin, const QVariantMap &tags, const QString &senderLogin,
MessageBuilder &builder, std::shared_ptr<MessageThread> &thread, bool isNew)
std::shared_ptr<MessageThread> &thread,
bool isNew)
{ {
const auto &currentLogin = const auto &currentLogin =
getApp()->getAccounts()->twitch.getCurrent()->getUserName(); getApp()->getAccounts()->twitch.getCurrent()->getUserName();
if (thread->subscribed()) if (thread->subscribed())
{ {
builder.message().flags.set(MessageFlag::SubscribedThread); return true;
return;
} }
if (thread->unsubscribed()) if (thread->unsubscribed())
{ {
return; return false;
} }
if (getSettings()->autoSubToParticipatedThreads) if (getSettings()->autoSubToParticipatedThreads)
@ -154,8 +151,7 @@ void updateReplyParticipatedStatus(const QVariantMap &tags,
if (name == currentLogin) if (name == currentLogin)
{ {
thread->markSubscribed(); thread->markSubscribed();
builder.message().flags.set(MessageFlag::SubscribedThread); return true; // already marked as participated
return; // already marked as participated
} }
} }
} }
@ -166,6 +162,8 @@ void updateReplyParticipatedStatus(const QVariantMap &tags,
// don't set the highlight here // don't set the highlight here
} }
} }
return false;
} }
ChannelPtr channelOrEmptyByTarget(const QString &target, ChannelPtr channelOrEmptyByTarget(const QString &target,
@ -242,10 +240,18 @@ QMap<QString, QString> parseBadges(const QString &badgesString)
return badges; return badges;
} }
void populateReply(TwitchChannel *channel, Communi::IrcMessage *message, struct ReplyContext {
const std::vector<MessagePtr> &otherLoaded, std::shared_ptr<MessageThread> thread;
MessageBuilder &builder) MessagePtr parent;
bool highlight = false;
};
[[nodiscard]] ReplyContext getReplyContext(
TwitchChannel *channel, Communi::IrcMessage *message,
const std::vector<MessagePtr> &otherLoaded)
{ {
ReplyContext ctx;
const auto &tags = message->tags(); const auto &tags = message->tags();
if (const auto it = tags.find("reply-thread-parent-msg-id"); if (const auto it = tags.find("reply-thread-parent-msg-id");
it != tags.end()) it != tags.end())
@ -259,9 +265,9 @@ void populateReply(TwitchChannel *channel, Communi::IrcMessage *message,
if (owned) if (owned)
{ {
// Thread already exists (has a reply) // Thread already exists (has a reply)
updateReplyParticipatedStatus(tags, message->nick(), builder, ctx.highlight = shouldHighlightReplyThread(
owned, false); tags, message->nick(), owned, false);
builder.setThread(owned); ctx.thread = owned;
rootThread = owned; rootThread = owned;
} }
} }
@ -295,10 +301,10 @@ void populateReply(TwitchChannel *channel, Communi::IrcMessage *message,
{ {
std::shared_ptr<MessageThread> newThread = std::shared_ptr<MessageThread> newThread =
std::make_shared<MessageThread>(foundMessage); std::make_shared<MessageThread>(foundMessage);
updateReplyParticipatedStatus(tags, message->nick(), builder, ctx.highlight = shouldHighlightReplyThread(
newThread, true); tags, message->nick(), newThread, true);
builder.setThread(newThread); ctx.thread = newThread;
rootThread = newThread; rootThread = newThread;
// Store weak reference to thread in channel // Store weak reference to thread in channel
channel->addReplyThread(newThread); channel->addReplyThread(newThread);
@ -313,7 +319,7 @@ void populateReply(TwitchChannel *channel, Communi::IrcMessage *message,
{ {
if (rootThread) if (rootThread)
{ {
builder.setParent(rootThread->root()); ctx.parent = rootThread->root();
} }
} }
else else
@ -324,7 +330,7 @@ void populateReply(TwitchChannel *channel, Communi::IrcMessage *message,
auto thread = parentThreadIt->second.lock(); auto thread = parentThreadIt->second.lock();
if (thread) if (thread)
{ {
builder.setParent(thread->root()); ctx.parent = thread->root();
} }
} }
else else
@ -332,12 +338,14 @@ void populateReply(TwitchChannel *channel, Communi::IrcMessage *message,
auto parent = channel->findMessage(parentID); auto parent = channel->findMessage(parentID);
if (parent) if (parent)
{ {
builder.setParent(parent); ctx.parent = parent;
} }
} }
} }
} }
} }
return ctx;
} }
std::optional<ClearChatMessage> parseClearChatMessage( std::optional<ClearChatMessage> parseClearChatMessage(
@ -705,7 +713,13 @@ std::vector<MessagePtr> IrcMessageHandler::parseMessageWithReply(
privMsg->isAction()); privMsg->isAction());
builder.setMessageOffset(messageOffset); builder.setMessageOffset(messageOffset);
populateReply(tc, message, otherLoaded, builder); auto replyCtx = getReplyContext(tc, message, otherLoaded);
builder.setThread(std::move(replyCtx.thread));
builder.setParent(std::move(replyCtx.parent));
if (replyCtx.highlight)
{
builder.message().flags.set(MessageFlag::SubscribedThread);
}
if (!builder.isIgnored()) if (!builder.isIgnored())
{ {
@ -1522,8 +1536,7 @@ void IrcMessageHandler::addMessage(Communi::IrcMessage *message,
QString content = originalContent; QString content = originalContent;
int messageOffset = stripLeadingReplyMention(tags, content); int messageOffset = stripLeadingReplyMention(tags, content);
MessageBuilder builder(channel, message, args, content, isAction); ReplyContext replyCtx;
builder.setMessageOffset(messageOffset);
if (const auto it = tags.find("reply-thread-parent-msg-id"); if (const auto it = tags.find("reply-thread-parent-msg-id");
it != tags.end()) it != tags.end())
@ -1535,9 +1548,9 @@ void IrcMessageHandler::addMessage(Communi::IrcMessage *message,
{ {
// Thread already exists (has a reply) // Thread already exists (has a reply)
auto thread = threadIt->second.lock(); auto thread = threadIt->second.lock();
updateReplyParticipatedStatus(tags, message->nick(), builder, replyCtx.highlight = shouldHighlightReplyThread(
thread, false); tags, message->nick(), thread, false);
builder.setThread(thread); replyCtx.thread = thread;
rootThread = thread; rootThread = thread;
} }
else else
@ -1548,10 +1561,10 @@ void IrcMessageHandler::addMessage(Communi::IrcMessage *message,
{ {
// Found root reply message // Found root reply message
auto newThread = std::make_shared<MessageThread>(root); auto newThread = std::make_shared<MessageThread>(root);
updateReplyParticipatedStatus(tags, message->nick(), builder, replyCtx.highlight = shouldHighlightReplyThread(
newThread, true); tags, message->nick(), newThread, true);
builder.setThread(newThread); replyCtx.thread = newThread;
rootThread = newThread; rootThread = newThread;
// Store weak reference to thread in channel // Store weak reference to thread in channel
channel->addReplyThread(newThread); channel->addReplyThread(newThread);
@ -1566,7 +1579,7 @@ void IrcMessageHandler::addMessage(Communi::IrcMessage *message,
{ {
if (rootThread) if (rootThread)
{ {
builder.setParent(rootThread->root()); replyCtx.parent = rootThread->root();
} }
} }
else else
@ -1577,7 +1590,7 @@ void IrcMessageHandler::addMessage(Communi::IrcMessage *message,
auto thread = parentThreadIt->second.lock(); auto thread = parentThreadIt->second.lock();
if (thread) if (thread)
{ {
builder.setParent(thread->root()); replyCtx.parent = thread->root();
} }
} }
else else
@ -1585,13 +1598,23 @@ void IrcMessageHandler::addMessage(Communi::IrcMessage *message,
auto parent = channel->findMessage(parentID); auto parent = channel->findMessage(parentID);
if (parent) if (parent)
{ {
builder.setParent(parent); replyCtx.parent = parent;
} }
} }
} }
} }
} }
MessageBuilder builder(channel, message, args, content, isAction);
builder.setMessageOffset(messageOffset);
builder.setThread(std::move(replyCtx.thread));
builder.setParent(std::move(replyCtx.parent));
if (replyCtx.highlight)
{
builder.message().flags.set(MessageFlag::SubscribedThread);
}
if (isSub || !builder.isIgnored()) if (isSub || !builder.isIgnored())
{ {
if (isSub) if (isSub)