diff --git a/src/providers/chatterino/ChatterinoBadges.cpp b/src/providers/chatterino/ChatterinoBadges.cpp index 433121093..446dfb10a 100644 --- a/src/providers/chatterino/ChatterinoBadges.cpp +++ b/src/providers/chatterino/ChatterinoBadges.cpp @@ -4,14 +4,11 @@ #include #include #include +#include #include "common/NetworkRequest.hpp" #include "common/Outcome.hpp" #include "messages/Emote.hpp" -#include - -#include - namespace chatterino { void ChatterinoBadges::initialize(Settings &settings, Paths &paths) { @@ -24,6 +21,8 @@ ChatterinoBadges::ChatterinoBadges() boost::optional ChatterinoBadges::getBadge(const UserId &id) { + std::shared_lock lock(this->mutex_); + auto it = badgeMap.find(id.string); if (it != badgeMap.end()) { @@ -37,8 +36,12 @@ void ChatterinoBadges::loadChatterinoBadges() static QUrl url("https://api.chatterino.com/badges"); NetworkRequest(url) + .concurrent() .onSuccess([this](auto result) -> Outcome { auto jsonRoot = result.parseJson(); + + std::unique_lock lock(this->mutex_); + int index = 0; for (const auto &jsonBadge_ : jsonRoot.value("badges").toArray()) { diff --git a/src/providers/chatterino/ChatterinoBadges.hpp b/src/providers/chatterino/ChatterinoBadges.hpp index 62c81a65d..f80a43b0b 100644 --- a/src/providers/chatterino/ChatterinoBadges.hpp +++ b/src/providers/chatterino/ChatterinoBadges.hpp @@ -2,11 +2,11 @@ #include #include - -#include "common/Aliases.hpp" - -#include +#include +#include #include +#include "common/Aliases.hpp" +#include "util/QStringHash.hpp" namespace chatterino { @@ -23,7 +23,10 @@ public: private: void loadChatterinoBadges(); - std::map badgeMap; + + std::shared_mutex mutex_; + + std::unordered_map badgeMap; std::vector emotes; }; diff --git a/src/providers/ffz/FfzBadges.cpp b/src/providers/ffz/FfzBadges.cpp index d6a5f8421..51c754042 100644 --- a/src/providers/ffz/FfzBadges.cpp +++ b/src/providers/ffz/FfzBadges.cpp @@ -4,14 +4,13 @@ #include #include #include +#include +#include +#include #include "common/NetworkRequest.hpp" #include "common/Outcome.hpp" #include "messages/Emote.hpp" -#include - -#include - namespace chatterino { void FfzBadges::initialize(Settings &settings, Paths &paths) @@ -21,6 +20,8 @@ void FfzBadges::initialize(Settings &settings, Paths &paths) boost::optional FfzBadges::getBadge(const UserId &id) { + std::shared_lock lock(this->mutex_); + auto it = this->badgeMap.find(id.string); if (it != this->badgeMap.end()) { @@ -30,6 +31,8 @@ boost::optional FfzBadges::getBadge(const UserId &id) } boost::optional FfzBadges::getBadgeColor(const UserId &id) { + std::shared_lock lock(this->mutex_); + auto badgeIt = this->badgeMap.find(id.string); if (badgeIt != this->badgeMap.end()) { @@ -49,6 +52,8 @@ void FfzBadges::loadFfzBadges() NetworkRequest(url) .onSuccess([this](auto result) -> Outcome { + std::unique_lock lock(this->mutex_); + auto jsonRoot = result.parseJson(); int index = 0; for (const auto &jsonBadge_ : jsonRoot.value("badges").toArray()) diff --git a/src/providers/ffz/FfzBadges.hpp b/src/providers/ffz/FfzBadges.hpp index 30a6857a8..57632bc39 100644 --- a/src/providers/ffz/FfzBadges.hpp +++ b/src/providers/ffz/FfzBadges.hpp @@ -4,8 +4,10 @@ #include #include "common/Aliases.hpp" +#include "util/QStringHash.hpp" #include +#include #include namespace chatterino { @@ -24,9 +26,12 @@ public: private: void loadFfzBadges(); - std::map badgeMap; + + std::shared_mutex mutex_; + + std::unordered_map badgeMap; std::vector badges; - std::map colorMap; + std::unordered_map colorMap; }; } // namespace chatterino diff --git a/src/providers/twitch/TwitchAccount.cpp b/src/providers/twitch/TwitchAccount.cpp index b0e2a6ccd..ff6d23859 100644 --- a/src/providers/twitch/TwitchAccount.cpp +++ b/src/providers/twitch/TwitchAccount.cpp @@ -101,14 +101,17 @@ void TwitchAccount::loadBlocks() getHelix()->loadBlocks( getApp()->accounts->twitch.getCurrent()->userId_, [this](std::vector blocks) { - std::lock_guard lock(this->ignoresMutex_); - this->ignores_.clear(); + auto ignores = this->ignores_.access(); + auto userIds = this->ignoresUserIds_.access(); + ignores->clear(); + userIds->clear(); for (const HelixBlock &block : blocks) { TwitchUser blockedUser; blockedUser.fromHelixBlock(block); - this->ignores_.insert(blockedUser); + ignores->insert(blockedUser); + userIds->insert(blockedUser.id); } }, [] { @@ -125,9 +128,11 @@ void TwitchAccount::blockUser(QString userId, std::function onSuccess, TwitchUser blockedUser; blockedUser.id = userId; { - std::lock_guard lock(this->ignoresMutex_); + auto ignores = this->ignores_.access(); + auto userIds = this->ignoresUserIds_.access(); - this->ignores_.insert(blockedUser); + ignores->insert(blockedUser); + userIds->insert(blockedUser.id); } onSuccess(); }, @@ -143,9 +148,11 @@ void TwitchAccount::unblockUser(QString userId, std::function onSuccess, TwitchUser ignoredUser; ignoredUser.id = userId; { - std::lock_guard lock(this->ignoresMutex_); + auto ignores = this->ignores_.access(); + auto userIds = this->ignoresUserIds_.access(); - this->ignores_.erase(ignoredUser); + ignores->erase(ignoredUser); + userIds->erase(ignoredUser.id); } onSuccess(); }, @@ -169,11 +176,14 @@ void TwitchAccount::checkFollow(const QString targetUserID, [] {}); } -std::set TwitchAccount::getBlocks() const +AccessGuard> TwitchAccount::accessBlocks() const { - std::lock_guard lock(this->ignoresMutex_); + return this->ignores_.accessConst(); +} - return this->ignores_; +AccessGuard> TwitchAccount::accessBlockedUserIds() const +{ + return this->ignoresUserIds_.accessConst(); } void TwitchAccount::loadEmotes() diff --git a/src/providers/twitch/TwitchAccount.hpp b/src/providers/twitch/TwitchAccount.hpp index 3b2dab951..cde25ddc6 100644 --- a/src/providers/twitch/TwitchAccount.hpp +++ b/src/providers/twitch/TwitchAccount.hpp @@ -106,7 +106,8 @@ public: void checkFollow(const QString targetUserID, std::function onFinished); - std::set getBlocks() const; + AccessGuard> accessBlockedUserIds() const; + AccessGuard> accessBlocks() const; void loadEmotes(); void loadUserstateEmotes(QStringList emoteSetKeys); @@ -128,7 +129,8 @@ private: mutable std::mutex ignoresMutex_; QElapsedTimer userstateEmotesTimer_; - std::set ignores_; + UniqueAccess> ignores_; + UniqueAccess> ignoresUserIds_; // std::map emotes; UniqueAccess emotes_; diff --git a/src/providers/twitch/TwitchChannel.cpp b/src/providers/twitch/TwitchChannel.cpp index 2b55eb32d..bd4be9a5e 100644 --- a/src/providers/twitch/TwitchChannel.cpp +++ b/src/providers/twitch/TwitchChannel.cpp @@ -720,6 +720,7 @@ void TwitchChannel::loadRecentMessages() .arg(getSettings()->twitchMessageHistoryLimit); NetworkRequest(url) + .concurrent() .onSuccess([weak = weakOf(this)](auto result) -> Outcome { auto shared = weak.lock(); if (!shared) diff --git a/src/providers/twitch/TwitchMessageBuilder.cpp b/src/providers/twitch/TwitchMessageBuilder.cpp index d3108bd04..182e88720 100644 --- a/src/providers/twitch/TwitchMessageBuilder.cpp +++ b/src/providers/twitch/TwitchMessageBuilder.cpp @@ -143,28 +143,28 @@ bool TwitchMessageBuilder::isIgnored() const { auto sourceUserID = this->tags.value("user-id").toString(); - for (const auto &user : app->accounts->twitch.getCurrent()->getBlocks()) - { - if (sourceUserID == user.id) - { - switch (static_cast( - getSettings()->showBlockedUsersMessages.getValue())) - { - case ShowIgnoredUsersMessages::IfModerator: - if (this->channel->isMod() || - this->channel->isBroadcaster()) - return false; - break; - case ShowIgnoredUsersMessages::IfBroadcaster: - if (this->channel->isBroadcaster()) - return false; - break; - case ShowIgnoredUsersMessages::Never: - break; - } + auto blocks = + app->accounts->twitch.getCurrent()->accessBlockedUserIds(); - return true; + if (auto it = blocks->find(sourceUserID); it != blocks->end()) + { + switch (static_cast( + getSettings()->showBlockedUsersMessages.getValue())) + { + case ShowIgnoredUsersMessages::IfModerator: + if (this->channel->isMod() || + this->channel->isBroadcaster()) + return false; + break; + case ShowIgnoredUsersMessages::IfBroadcaster: + if (this->channel->isBroadcaster()) + return false; + break; + case ShowIgnoredUsersMessages::Never: + break; } + + return true; } } diff --git a/src/widgets/dialogs/UserInfoPopup.cpp b/src/widgets/dialogs/UserInfoPopup.cpp index 27dfb5cf6..b27e2e698 100644 --- a/src/widgets/dialogs/UserInfoPopup.cpp +++ b/src/widgets/dialogs/UserInfoPopup.cpp @@ -697,13 +697,11 @@ void UserInfoPopup::updateUserData() // get ignore state bool isIgnoring = false; - for (const auto &blockedUser : currentUser->getBlocks()) + + if (auto blocks = currentUser->accessBlockedUserIds(); + blocks->find(user.id) != blocks->end()) { - if (user.id == blockedUser.id) - { - isIgnoring = true; - break; - } + isIgnoring = true; } // get ignoreHighlights state diff --git a/src/widgets/settingspages/IgnoresPage.cpp b/src/widgets/settingspages/IgnoresPage.cpp index 73843f9f7..ccb494d17 100644 --- a/src/widgets/settingspages/IgnoresPage.cpp +++ b/src/widgets/settingspages/IgnoresPage.cpp @@ -123,7 +123,10 @@ void IgnoresPage::onShow() } QStringList users; - for (const auto &blockedUser : user->getBlocks()) + + auto blocks = app->accounts->twitch.getCurrent()->accessBlocks(); + + for (const auto &blockedUser : *blocks) { users << blockedUser.name; }