From e38c64bac3220a5cedb927809ea541e555079259 Mon Sep 17 00:00:00 2001 From: pajlada Date: Sat, 3 May 2025 11:32:55 +0200 Subject: [PATCH] fix: don't include blocked users in join/part messages (#6181) --- CHANGELOG.md | 1 + src/common/ChannelChatters.cpp | 38 +++++++++++++++---- src/common/ChannelChatters.hpp | 4 +- .../commands/builtin/twitch/Block.cpp | 4 +- src/controllers/ignores/IgnoreController.cpp | 27 +++++++++---- src/controllers/ignores/IgnoreController.hpp | 1 + src/providers/twitch/IrcMessageHandler.cpp | 6 ++- src/providers/twitch/TwitchAccount.cpp | 27 ++++++++++--- src/providers/twitch/TwitchAccount.hpp | 12 +++--- src/providers/twitch/TwitchUser.hpp | 6 +++ src/widgets/dialogs/UserInfoPopup.cpp | 4 +- tests/src/IrcMessageHandler.cpp | 2 +- 12 files changed, 98 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 19a0e369..62957f79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ - Bugfix: Fixed the emote popup erroneously logging messages to the `Other` directory. (#6165) - Bugfix: Handle CMD + BACKSPACE behavior explicitly in main chat dialog input for macOS. (#6111) - Bugfix: Fixed a small typo in the settings page. (#6134) +- Bugfix: Fixed blocked users showing up in "Users joined:" and "Users parted:" messages. (#6181) - Bugfix: Fixed an issue where Splits could get lost by dragging it onto your Recycle Bin. (#6147) - Bugfix: Fixed some Twitch commands not getting tab-completed correctly. (#6143) - Bugfix: Fixed shared chat badges displaying pixelated when Chatterino is scaled too much. (#6146) diff --git a/src/common/ChannelChatters.cpp b/src/common/ChannelChatters.cpp index 575b9030..52f52262 100644 --- a/src/common/ChannelChatters.cpp +++ b/src/common/ChannelChatters.cpp @@ -1,8 +1,10 @@ #include "common/ChannelChatters.hpp" #include "common/Channel.hpp" -#include "messages/Message.hpp" +#include "controllers/ignores/IgnoreController.hpp" +#include "debug/AssertInGuiThread.hpp" #include "messages/MessageBuilder.hpp" +#include "providers/twitch/TwitchAccount.hpp" #include @@ -25,10 +27,21 @@ void ChannelChatters::addRecentChatter(const QString &user) chatters->addRecentChatter(user); } -void ChannelChatters::addJoinedUser(const QString &user) +void ChannelChatters::addJoinedUser(const QString &user, bool isMod, + bool isBroadcaster) { - auto joinedUsers = this->joinedUsers_.access(); - joinedUsers->append(user); + assertInGuiThread(); + + if (isIgnoredMessage(IgnoredMessageParameters{ + .twitchUserLogin = user, + .isMod = isMod, + .isBroadcaster = isBroadcaster, + })) + { + return; + } + + this->joinedUsers_.access()->append(user); if (!this->joinedUsersMergeQueued_) { @@ -50,10 +63,21 @@ void ChannelChatters::addJoinedUser(const QString &user) } } -void ChannelChatters::addPartedUser(const QString &user) +void ChannelChatters::addPartedUser(const QString &user, bool isMod, + bool isBroadcaster) { - auto partedUsers = this->partedUsers_.access(); - partedUsers->append(user); + assertInGuiThread(); + + if (isIgnoredMessage(IgnoredMessageParameters{ + .twitchUserLogin = user, + .isMod = isMod, + .isBroadcaster = isBroadcaster, + })) + { + return; + } + + this->partedUsers_.access()->append(user); if (!this->partedUsersMergeQueued_) { diff --git a/src/common/ChannelChatters.hpp b/src/common/ChannelChatters.hpp index b15717dc..8ba4b130 100644 --- a/src/common/ChannelChatters.hpp +++ b/src/common/ChannelChatters.hpp @@ -22,8 +22,8 @@ public: SharedAccessGuard accessChatters() const; void addRecentChatter(const QString &user); - void addJoinedUser(const QString &user); - void addPartedUser(const QString &user); + void addJoinedUser(const QString &user, bool isMod, bool isBroadcaster); + void addPartedUser(const QString &user, bool isMod, bool isBroadcaster); const QColor getUserColor(const QString &user); void setUserColor(const QString &user, const QColor &color); void updateOnlineChatters(const std::unordered_set &usernames); diff --git a/src/controllers/commands/builtin/twitch/Block.cpp b/src/controllers/commands/builtin/twitch/Block.cpp index 7e0423d4..cc2bffd0 100644 --- a/src/controllers/commands/builtin/twitch/Block.cpp +++ b/src/controllers/commands/builtin/twitch/Block.cpp @@ -53,7 +53,7 @@ QString blockUser(const CommandContext &ctx) [currentUser, channel{ctx.channel}, target](const HelixUser &targetUser) { getApp()->getAccounts()->twitch.getCurrent()->blockUser( - targetUser.id, nullptr, + targetUser.id, targetUser.login, nullptr, [channel, target, targetUser] { channel->addSystemMessage( QString("You successfully blocked user %1") @@ -125,7 +125,7 @@ QString unblockUser(const CommandContext &ctx) target, [currentUser, channel{ctx.channel}, target](const auto &targetUser) { getApp()->getAccounts()->twitch.getCurrent()->unblockUser( - targetUser.id, nullptr, + targetUser.id, targetUser.login, nullptr, [channel, target, targetUser] { channel->addSystemMessage( QString("You successfully unblocked user %1") diff --git a/src/controllers/ignores/IgnoreController.cpp b/src/controllers/ignores/IgnoreController.cpp index f8e60b6b..e03df037 100644 --- a/src/controllers/ignores/IgnoreController.cpp +++ b/src/controllers/ignores/IgnoreController.cpp @@ -149,16 +149,27 @@ bool isIgnoredMessage(IgnoredMessageParameters &¶ms) } } - if (!params.twitchUserID.isEmpty() && - getSettings()->enableTwitchBlockedUsers) + if (getSettings()->enableTwitchBlockedUsers) { - auto sourceUserID = params.twitchUserID; + bool isBlocked = false; + + if (!params.twitchUserID.isEmpty()) + { + isBlocked = getApp() + ->getAccounts() + ->twitch.getCurrent() + ->blockedUserIds() + .contains(params.twitchUserID); + } + else if (!params.twitchUserLogin.isEmpty()) + { + isBlocked = getApp() + ->getAccounts() + ->twitch.getCurrent() + ->blockedUserLogins() + .contains(params.twitchUserLogin); + } - bool isBlocked = getApp() - ->getAccounts() - ->twitch.getCurrent() - ->blockedUserIds() - .contains(sourceUserID); if (isBlocked) { switch (static_cast( diff --git a/src/controllers/ignores/IgnoreController.hpp b/src/controllers/ignores/IgnoreController.hpp index 95553153..16ed8a50 100644 --- a/src/controllers/ignores/IgnoreController.hpp +++ b/src/controllers/ignores/IgnoreController.hpp @@ -15,6 +15,7 @@ struct IgnoredMessageParameters { QString message; QString twitchUserID; + QString twitchUserLogin; bool isMod; bool isBroadcaster; }; diff --git a/src/providers/twitch/IrcMessageHandler.cpp b/src/providers/twitch/IrcMessageHandler.cpp index 598dcaee..ac57870e 100644 --- a/src/providers/twitch/IrcMessageHandler.cpp +++ b/src/providers/twitch/IrcMessageHandler.cpp @@ -934,7 +934,8 @@ void IrcMessageHandler::handleJoinMessage(Communi::IrcMessage *message) } else if (getSettings()->showJoins.getValue()) { - twitchChannel->addJoinedUser(message->nick()); + twitchChannel->addJoinedUser(message->nick(), twitchChannel->isMod(), + twitchChannel->isBroadcaster()); } } @@ -954,7 +955,8 @@ void IrcMessageHandler::handlePartMessage(Communi::IrcMessage *message) if (message->nick() != selfAccountName && getSettings()->showParts.getValue()) { - twitchChannel->addPartedUser(message->nick()); + twitchChannel->addPartedUser(message->nick(), twitchChannel->isMod(), + twitchChannel->isBroadcaster()); } if (message->nick() == selfAccountName) diff --git a/src/providers/twitch/TwitchAccount.cpp b/src/providers/twitch/TwitchAccount.cpp index 3dbbe7a1..586cbd06 100644 --- a/src/providers/twitch/TwitchAccount.cpp +++ b/src/providers/twitch/TwitchAccount.cpp @@ -117,6 +117,7 @@ void TwitchAccount::loadBlocks() this->blockToken_ = token; this->ignores_.clear(); this->ignoresUserIds_.clear(); + this->ignoresUserLogins_.clear(); getHelix()->loadBlocks( getApp()->getAccounts()->twitch.getCurrent()->userId_, @@ -129,6 +130,7 @@ void TwitchAccount::loadBlocks() blockedUser.fromHelixBlock(block); this->ignores_.insert(blockedUser); this->ignoresUserIds_.insert(blockedUser.id); + this->ignoresUserLogins_.insert(blockedUser.name); } }, [](auto error) { @@ -138,51 +140,60 @@ void TwitchAccount::loadBlocks() std::move(token)); } -void TwitchAccount::blockUser(const QString &userId, const QObject *caller, +void TwitchAccount::blockUser(const QString &userId, const QString &userLogin, + const QObject *caller, std::function onSuccess, std::function onFailure) { getHelix()->blockUser( userId, caller, - [this, userId, onSuccess = std::move(onSuccess)] { + [this, userId, userLogin, onSuccess = std::move(onSuccess)] { assertInGuiThread(); TwitchUser blockedUser; blockedUser.id = userId; + blockedUser.name = userLogin; this->ignores_.insert(blockedUser); this->ignoresUserIds_.insert(blockedUser.id); + this->ignoresUserLogins_.insert(blockedUser.name); onSuccess(); }, std::move(onFailure)); } -void TwitchAccount::unblockUser(const QString &userId, const QObject *caller, +void TwitchAccount::unblockUser(const QString &userId, const QString &userLogin, + const QObject *caller, std::function onSuccess, std::function onFailure) { getHelix()->unblockUser( userId, caller, - [this, userId, onSuccess = std::move(onSuccess)] { + [this, userId, userLogin, onSuccess = std::move(onSuccess)] { assertInGuiThread(); TwitchUser ignoredUser; ignoredUser.id = userId; + ignoredUser.name = userLogin; this->ignores_.erase(ignoredUser); this->ignoresUserIds_.erase(ignoredUser.id); + this->ignoresUserLogins_.erase(ignoredUser.name); onSuccess(); }, std::move(onFailure)); } -void TwitchAccount::blockUserLocally(const QString &userID) +void TwitchAccount::blockUserLocally(const QString &userID, + const QString &userLogin) { assertInGuiThread(); assert(getApp()->isTest()); TwitchUser blockedUser; blockedUser.id = userID; + blockedUser.name = userLogin; this->ignores_.insert(blockedUser); this->ignoresUserIds_.insert(blockedUser.id); + this->ignoresUserLogins_.insert(blockedUser.name); } const std::unordered_set &TwitchAccount::blocks() const @@ -197,6 +208,12 @@ const std::unordered_set &TwitchAccount::blockedUserIds() const return this->ignoresUserIds_; } +const std::unordered_set &TwitchAccount::blockedUserLogins() const +{ + assertInGuiThread(); + return this->ignoresUserLogins_; +} + // AutoModActions void TwitchAccount::autoModAllow(const QString msgID, ChannelPtr channel) { diff --git a/src/providers/twitch/TwitchAccount.hpp b/src/providers/twitch/TwitchAccount.hpp index fe191a85..cd0901fb 100644 --- a/src/providers/twitch/TwitchAccount.hpp +++ b/src/providers/twitch/TwitchAccount.hpp @@ -64,17 +64,18 @@ public: bool isAnon() const; void loadBlocks(); - void blockUser(const QString &userId, const QObject *caller, - std::function onSuccess, + void blockUser(const QString &userId, const QString &userLogin, + const QObject *caller, std::function onSuccess, std::function onFailure); - void unblockUser(const QString &userId, const QObject *caller, - std::function onSuccess, + void unblockUser(const QString &userId, const QString &userLogin, + const QObject *caller, std::function onSuccess, std::function onFailure); - void blockUserLocally(const QString &userID); + void blockUserLocally(const QString &userID, const QString &userLogin); [[nodiscard]] const std::unordered_set &blocks() const; [[nodiscard]] const std::unordered_set &blockedUserIds() const; + [[nodiscard]] const std::unordered_set &blockedUserLogins() const; // Automod actions void autoModAllow(const QString msgID, ChannelPtr channel); @@ -120,6 +121,7 @@ private: ScopedCancellationToken blockToken_; std::unordered_set ignores_; std::unordered_set ignoresUserIds_; + std::unordered_set ignoresUserLogins_; ScopedCancellationToken emoteToken_; UniqueAccess> emoteSets_; diff --git a/src/providers/twitch/TwitchUser.hpp b/src/providers/twitch/TwitchUser.hpp index 932e8829..1743eb3c 100644 --- a/src/providers/twitch/TwitchUser.hpp +++ b/src/providers/twitch/TwitchUser.hpp @@ -15,9 +15,15 @@ struct HelixBlock; struct HelixUser; struct TwitchUser { + /// The Twitch User ID (e.g. `117166826`) QString id; + + /// The Twitch User Login (e.g. `testaccount_420`) mutable QString name; + + // The Twitch User Display Name (e.g. `테스트계정420`) mutable QString displayName; + mutable QString profilePictureUrl; void update(const TwitchUser &other) const diff --git a/src/widgets/dialogs/UserInfoPopup.cpp b/src/widgets/dialogs/UserInfoPopup.cpp index b39e0d1d..9197fcc7 100644 --- a/src/widgets/dialogs/UserInfoPopup.cpp +++ b/src/widgets/dialogs/UserInfoPopup.cpp @@ -661,7 +661,7 @@ void UserInfoPopup::installEvents() this->ui_.block->setEnabled(false); getApp()->getAccounts()->twitch.getCurrent()->unblockUser( - this->userId_, this, + this->userId_, this->userName_, this, [this, reenableBlockCheckbox, currentUser] { this->channel_->addSystemMessage( QString("You successfully unblocked user %1") @@ -702,7 +702,7 @@ void UserInfoPopup::installEvents() } getApp()->getAccounts()->twitch.getCurrent()->blockUser( - this->userId_, this, + this->userId_, this->userName_, this, [this, reenableBlockCheckbox, currentUser] { this->channel_->addSystemMessage( QString("You successfully blocked user %1") diff --git a/tests/src/IrcMessageHandler.cpp b/tests/src/IrcMessageHandler.cpp index c4c845cd..a0fc31de 100644 --- a/tests/src/IrcMessageHandler.cpp +++ b/tests/src/IrcMessageHandler.cpp @@ -469,7 +469,7 @@ public: this->mockApplication->getAccounts() ->twitch.getCurrent() - ->blockUserLocally(u"12345"_s); + ->blockUserLocally(u"12345"_s, u"blocked"_s); auto makeBadge = [](QStringView platform) { return std::make_shared(Emote{