diff --git a/CHANGELOG.md b/CHANGELOG.md index 4976ddfaa1c..e5d81f9c74c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ - Minor: Moderators can now see which mods start and cancel raids. (#5563) - Minor: The emote popup now reloads when Twitch emotes are reloaded. (#5580) - Minor: Added `--login ` CLI argument to specify which account to start logged in as. (#5626) +- Minor: When blocking a channel, Chatterino will now warn you about that action. (#5615) - Bugfix: Fixed tab move animation occasionally failing to start after closing a tab. (#5426, #5612) - Bugfix: If a network request errors with 200 OK, Qt's error code is now reported instead of the HTTP status. (#5378) - Bugfix: Fixed restricted users usernames not being clickable. (#5405) diff --git a/mocks/include/mocks/Helix.hpp b/mocks/include/mocks/Helix.hpp index 5156de55750..fe309f0f8b8 100644 --- a/mocks/include/mocks/Helix.hpp +++ b/mocks/include/mocks/Helix.hpp @@ -422,7 +422,7 @@ class Helix : public IHelix // get followed channel MOCK_METHOD( void, getFollowedChannel, - (QString userID, QString broadcasterID, + (QString userID, QString broadcasterID, const QObject *caller, ResultCallback> successCallback, FailureCallback failureCallback), (override)); diff --git a/src/providers/twitch/TwitchChannel.cpp b/src/providers/twitch/TwitchChannel.cpp index 48bc1ee1976..5e05db88655 100644 --- a/src/providers/twitch/TwitchChannel.cpp +++ b/src/providers/twitch/TwitchChannel.cpp @@ -274,7 +274,7 @@ void TwitchChannel::refreshTwitchChannelEmotes(bool manualRefresh) getHelix()->getFollowedChannel( getApp()->getAccounts()->twitch.getCurrent()->getUserId(), - this->roomId(), + this->roomId(), nullptr, [weak{this->weak_from_this()}, makeEmotes](const auto &chan) { auto self = std::dynamic_pointer_cast(weak.lock()); if (!self || !chan) diff --git a/src/providers/twitch/api/Helix.cpp b/src/providers/twitch/api/Helix.cpp index a756a0f47a2..b16320dbb54 100644 --- a/src/providers/twitch/api/Helix.cpp +++ b/src/providers/twitch/api/Helix.cpp @@ -3138,7 +3138,7 @@ void Helix::getUserEmotes( } void Helix::getFollowedChannel( - QString userID, QString broadcasterID, + QString userID, QString broadcasterID, const QObject *caller, ResultCallback> successCallback, FailureCallback failureCallback) { @@ -3147,6 +3147,7 @@ void Helix::getFollowedChannel( {u"user_id"_s, userID}, {u"broadcaster_id"_s, broadcasterID}, }) + .caller(caller) .onSuccess([successCallback](auto result) { if (result.status() != 200) { diff --git a/src/providers/twitch/api/Helix.hpp b/src/providers/twitch/api/Helix.hpp index ec82f165441..38eebf3b3e2 100644 --- a/src/providers/twitch/api/Helix.hpp +++ b/src/providers/twitch/api/Helix.hpp @@ -1143,7 +1143,7 @@ class IHelix /// https://dev.twitch.tv/docs/api/reference/#get-followed-channels /// (non paginated) virtual void getFollowedChannel( - QString userID, QString broadcasterID, + QString userID, QString broadcasterID, const QObject *caller, ResultCallback> successCallback, FailureCallback failureCallback) = 0; @@ -1486,7 +1486,7 @@ class Helix final : public IHelix /// https://dev.twitch.tv/docs/api/reference/#get-followed-channels /// (non paginated) void getFollowedChannel( - QString userID, QString broadcasterID, + QString userID, QString broadcasterID, const QObject *caller, ResultCallback> successCallback, FailureCallback failureCallback) final; diff --git a/src/widgets/DraggablePopup.cpp b/src/widgets/DraggablePopup.cpp index 84a57c0f77d..b4ad4ff411f 100644 --- a/src/widgets/DraggablePopup.cpp +++ b/src/widgets/DraggablePopup.cpp @@ -41,6 +41,7 @@ DraggablePopup::DraggablePopup(bool closeAutomatically, QWidget *parent) : popupFlags | BaseWindow::DisableLayoutSave, parent) , lifetimeHack_(std::make_shared(false)) + , closeAutomatically_(closeAutomatically) , dragTimer_(this) { @@ -128,4 +129,14 @@ Button *DraggablePopup::createPinButton() return this->pinButton_; } +bool DraggablePopup::ensurePinned() +{ + if (this->closeAutomatically_ && !this->isPinned_) + { + this->togglePinned(); + return true; + } + return false; +} + } // namespace chatterino diff --git a/src/widgets/DraggablePopup.hpp b/src/widgets/DraggablePopup.hpp index bf82af0082c..97217c0df14 100644 --- a/src/widgets/DraggablePopup.hpp +++ b/src/widgets/DraggablePopup.hpp @@ -38,10 +38,18 @@ class DraggablePopup : public BaseWindow // button pixmap void togglePinned(); + /// Ensures that this popup is pinned (if it's expected to close automatically) + /// + /// @returns `true` if the popup was pinned as a result (i.e. if the popup + /// was unpinned and said to automatically close before) + bool ensurePinned(); + private: // isMoving_ is set to true if the user is holding the left mouse button down and has moved the mouse a small amount away from the original click point (startPosDrag_) bool isMoving_ = false; + bool closeAutomatically_ = false; + // startPosDrag_ is the coordinates where the user originally pressed the mouse button down to start dragging QPoint startPosDrag_; diff --git a/src/widgets/dialogs/UserInfoPopup.cpp b/src/widgets/dialogs/UserInfoPopup.cpp index fabae271d11..4a6e3364a55 100644 --- a/src/widgets/dialogs/UserInfoPopup.cpp +++ b/src/widgets/dialogs/UserInfoPopup.cpp @@ -2,6 +2,7 @@ #include "Application.hpp" #include "common/Channel.hpp" +#include "common/Literals.hpp" #include "common/network/NetworkRequest.hpp" #include "common/QLogging.hpp" #include "controllers/accounts/AccountController.hpp" @@ -37,6 +38,8 @@ #include #include +#include +#include #include #include #include @@ -141,6 +144,8 @@ int calculateTimeoutDuration(TimeoutButton timeout) namespace chatterino { +using namespace literals; + UserInfoPopup::UserInfoPopup(bool closeAutomatically, Split *split) : DraggablePopup(closeAutomatically, split) , split_(split) @@ -621,57 +626,72 @@ void UserInfoPopup::installEvents() return; } - switch (newState) + if (newState == Qt::Unchecked) { - case Qt::CheckState::Unchecked: { - this->ui_.block->setEnabled(false); - - getApp()->getAccounts()->twitch.getCurrent()->unblockUser( - this->userId_, this, - [this, reenableBlockCheckbox, currentUser] { - this->channel_->addSystemMessage( - QString("You successfully unblocked user %1") - .arg(this->userName_)); - reenableBlockCheckbox(); - }, - [this, reenableBlockCheckbox] { - this->channel_->addSystemMessage( - QString( - "User %1 couldn't be unblocked, an unknown " + this->ui_.block->setEnabled(false); + + getApp()->getAccounts()->twitch.getCurrent()->unblockUser( + this->userId_, this, + [this, reenableBlockCheckbox, currentUser] { + this->channel_->addSystemMessage( + QString("You successfully unblocked user %1") + .arg(this->userName_)); + reenableBlockCheckbox(); + }, + [this, reenableBlockCheckbox] { + this->channel_->addSystemMessage( + QString("User %1 couldn't be unblocked, an unknown " "error occurred!") - .arg(this->userName_)); - reenableBlockCheckbox(); - }); - } - break; + .arg(this->userName_)); + reenableBlockCheckbox(); + }); + return; + } - case Qt::CheckState::PartiallyChecked: { - // We deliberately ignore this state + if (newState == Qt::Checked) + { + this->ui_.block->setEnabled(false); + + bool wasPinned = this->ensurePinned(); + auto btn = QMessageBox::warning( + this, u"Blocking " % this->userName_, + u"Blocking %1 can cause unintended side-effects like unfollowing.\n\n"_s + "Are you sure you want to block %1?".arg(this->userName_), + QMessageBox::Yes | QMessageBox::Cancel, + QMessageBox::Cancel); + if (wasPinned) + { + this->togglePinned(); } - break; - - case Qt::CheckState::Checked: { - this->ui_.block->setEnabled(false); - - getApp()->getAccounts()->twitch.getCurrent()->blockUser( - this->userId_, this, - [this, reenableBlockCheckbox, currentUser] { - this->channel_->addSystemMessage( - QString("You successfully blocked user %1") - .arg(this->userName_)); - reenableBlockCheckbox(); - }, - [this, reenableBlockCheckbox] { - this->channel_->addSystemMessage( - QString( - "User %1 couldn't be blocked, an unknown " - "error occurred!") - .arg(this->userName_)); - reenableBlockCheckbox(); - }); + if (btn != QMessageBox::Yes) + { + reenableBlockCheckbox(); + QSignalBlocker blocker(this->ui_.block); + this->ui_.block->setCheckState(Qt::Unchecked); + return; } - break; + + getApp()->getAccounts()->twitch.getCurrent()->blockUser( + this->userId_, this, + [this, reenableBlockCheckbox, currentUser] { + this->channel_->addSystemMessage( + QString("You successfully blocked user %1") + .arg(this->userName_)); + reenableBlockCheckbox(); + }, + [this, reenableBlockCheckbox] { + this->channel_->addSystemMessage( + QString("User %1 couldn't be blocked, an " + "unknown error occurred!") + .arg(this->userName_)); + reenableBlockCheckbox(); + }); + return; } + + qCWarning(chatterinoWidget) + << "Unexpected check-state when blocking" << this->userName_ + << QMetaEnum::fromType().valueToKey(newState); }); // ignore highlights