Compare commits

...

6 commits

5 changed files with 68 additions and 36 deletions

View file

@ -4,7 +4,7 @@
- Major: Add option to show pronouns in user card. (#5442, #5583) - Major: Add option to show pronouns in user card. (#5442, #5583)
- Major: Release plugins alpha. (#5288) - Major: Release plugins alpha. (#5288)
- Major: Improve high-DPI support on Windows. (#4868, #5391) - Major: Improve high-DPI support on Windows. (#4868, #5391, #5664)
- Major: Added transparent overlay window (default keybind: <kbd>CTRL</kbd> + <kbd>ALT</kbd> + <kbd>N</kbd>). (#4746, #5643, #5659) - Major: Added transparent overlay window (default keybind: <kbd>CTRL</kbd> + <kbd>ALT</kbd> + <kbd>N</kbd>). (#4746, #5643, #5659)
- Minor: Removed the Ctrl+Shift+L hotkey for toggling the "live only" tab visibility state. (#5530) - Minor: Removed the Ctrl+Shift+L hotkey for toggling the "live only" tab visibility state. (#5530)
- Minor: Add support for Shared Chat messages. Shared chat messages can be filtered with the `flags.shared` filter variable, or with search using `is:shared`. Some messages like subscriptions are filtered on purpose to avoid confusion for the broadcaster. If you have both channels participating in Shared Chat open, only one of the message triggering your highlight will trigger. (#5606, #5625, #5661) - Minor: Add support for Shared Chat messages. Shared chat messages can be filtered with the `flags.shared` filter variable, or with search using `is:shared`. Some messages like subscriptions are filtered on purpose to avoid confusion for the broadcaster. If you have both channels participating in Shared Chat open, only one of the message triggering your highlight will trigger. (#5606, #5625, #5661)
@ -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

@ -1 +1 @@
Subproject commit f339d2f73730f8fee4412f5e4938717866ecef48 Subproject commit 88ee08eb3c3f3627ca54b90dafd1d63a6d4da96b

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 1 KiB

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)

View file

@ -876,6 +876,14 @@ bool BaseWindow::nativeEvent(const QByteArray &eventType, void *message,
} }
break; break;
case WM_DPICHANGED: {
// wait for Qt to process this message
postToThread([] {
getApp()->getWindows()->invalidateChannelViewBuffers();
});
}
break;
case WM_NCLBUTTONDOWN: case WM_NCLBUTTONDOWN:
case WM_NCLBUTTONUP: { case WM_NCLBUTTONUP: {
// WM_NCLBUTTON{DOWN, UP} gets called when the left mouse button // WM_NCLBUTTON{DOWN, UP} gets called when the left mouse button