From c7a2f4cc929681662e3ff0cf7e8d8e2f872039cf Mon Sep 17 00:00:00 2001 From: pajlada Date: Sun, 6 Sep 2020 06:46:35 -0400 Subject: [PATCH] Don't make follow requests based on the check follow response (#1906) This is done by deliberately setting and reading the enabled state of the widget whenever the stateChanged event happens. If the stateChanged event happens while the widget is not enabled, we know the event must have been triggered by our "check user follow state" event, and then we don't act upon that event --- CHANGELOG.md | 1 + src/widgets/dialogs/UserInfoPopup.cpp | 39 +++++++++++++++++++++------ 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 623ad1baa..73c2c3c97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Minor: Disable checking for updates on unsupported platforms (#1874) - Bugfix: Fix bug preventing users from setting the highlight color of the second entry in the "User" highlights tab (#1898) +- Bugfix: Fix bug where the "check user follow state" event could trigger a network request requesting the user to follow or unfollow a user. By itself its quite harmless as it just repeats to Twitch the same follow state we had, so no follows should have been lost by this but it meant there was a rogue network request that was fired that could cause a crash (#1906) - Bugfix: /usercard command will now respect the "Automatically close user popup" setting (#1918) - Bugfix: Handle symlinks properly when saving commands & settings (#1856, #1908) - Bugfix: Starting Chatterino in a minimized state after an update will no longer cause a crash diff --git a/src/widgets/dialogs/UserInfoPopup.cpp b/src/widgets/dialogs/UserInfoPopup.cpp index cc1665aac..4e773866b 100644 --- a/src/widgets/dialogs/UserInfoPopup.cpp +++ b/src/widgets/dialogs/UserInfoPopup.cpp @@ -310,22 +310,43 @@ void UserInfoPopup::installEvents() // follow QObject::connect( - this->ui_.follow, &QCheckBox::stateChanged, [this](int) mutable { + this->ui_.follow, &QCheckBox::stateChanged, + [this](int newState) mutable { auto currentUser = getApp()->accounts->twitch.getCurrent(); const auto reenableFollowCheckbox = [this] { this->ui_.follow->setEnabled(true); // }; - this->ui_.follow->setEnabled(false); - if (this->ui_.follow->isChecked()) + if (!this->ui_.follow->isEnabled()) { - currentUser->followUser(this->userId_, reenableFollowCheckbox); + // We received a state update while the checkbox was disabled + // This can only happen from the "check current follow state" call + // The state has been updated to properly reflect the users current follow state + reenableFollowCheckbox(); + return; } - else + + switch (newState) { - currentUser->unfollowUser(this->userId_, - reenableFollowCheckbox); + case Qt::CheckState::Unchecked: { + this->ui_.follow->setEnabled(false); + currentUser->unfollowUser(this->userId_, + reenableFollowCheckbox); + } + break; + + case Qt::CheckState::PartiallyChecked: { + // We deliberately ignore this state + } + break; + + case Qt::CheckState::Checked: { + this->ui_.follow->setEnabled(false); + currentUser->followUser(this->userId_, + reenableFollowCheckbox); + } + break; } }); @@ -445,6 +466,8 @@ void UserInfoPopup::updateLatestMessages() void UserInfoPopup::updateUserData() { + this->ui_.follow->setEnabled(false); + std::weak_ptr hack = this->hack_; const auto onUserFetchFailed = [this, hack] { @@ -520,8 +543,8 @@ void UserInfoPopup::updateUserData() } if (result != FollowResult_Failed) { - this->ui_.follow->setEnabled(true); this->ui_.follow->setChecked(result == FollowResult_Following); + this->ui_.follow->setEnabled(true); } });