Skip to content

Commit

Permalink
feat: show warning before blocking followed channel
Browse files Browse the repository at this point in the history
  • Loading branch information
Nerixyz committed Oct 2, 2024
1 parent 055f674 commit 619338c
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 38 deletions.
2 changes: 1 addition & 1 deletion src/providers/twitch/TwitchChannel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<TwitchChannel>(weak.lock());
if (!self || !chan)
Expand Down
3 changes: 2 additions & 1 deletion src/providers/twitch/api/Helix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3138,7 +3138,7 @@ void Helix::getUserEmotes(
}

void Helix::getFollowedChannel(
QString userID, QString broadcasterID,
QString userID, QString broadcasterID, const QObject *caller,
ResultCallback<std::optional<HelixFollowedChannel>> successCallback,
FailureCallback<QString> failureCallback)
{
Expand All @@ -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)
{
Expand Down
4 changes: 2 additions & 2 deletions src/providers/twitch/api/Helix.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::optional<HelixFollowedChannel>> successCallback,
FailureCallback<QString> failureCallback) = 0;

Expand Down Expand Up @@ -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<std::optional<HelixFollowedChannel>> successCallback,
FailureCallback<QString> failureCallback) final;

Expand Down
11 changes: 11 additions & 0 deletions src/widgets/DraggablePopup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ DraggablePopup::DraggablePopup(bool closeAutomatically, QWidget *parent)
: popupFlags | BaseWindow::DisableLayoutSave,
parent)
, lifetimeHack_(std::make_shared<bool>(false))
, closeAutomatically_(closeAutomatically)
, dragTimer_(this)

{
Expand Down Expand Up @@ -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
8 changes: 8 additions & 0 deletions src/widgets/DraggablePopup.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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_;

Expand Down
128 changes: 94 additions & 34 deletions src/widgets/dialogs/UserInfoPopup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -37,6 +38,8 @@

#include <QCheckBox>
#include <QDesktopServices>
#include <QMessageBox>
#include <QMetaEnum>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QPointer>
Expand Down Expand Up @@ -141,6 +144,8 @@ int calculateTimeoutDuration(TimeoutButton timeout)

namespace chatterino {

using namespace literals;

UserInfoPopup::UserInfoPopup(bool closeAutomatically, Split *split)
: DraggablePopup(closeAutomatically, split)
, split_(split)
Expand Down Expand Up @@ -621,38 +626,33 @@ 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;

case Qt::CheckState::PartiallyChecked: {
// We deliberately ignore this state
}
break;

case Qt::CheckState::Checked: {
this->ui_.block->setEnabled(false);
.arg(this->userName_));
reenableBlockCheckbox();
});
return;
}

if (newState == Qt::Checked)
{
this->ui_.block->setEnabled(false);
auto blockThisUser = [this, reenableBlockCheckbox,
currentUser] {
getApp()->getAccounts()->twitch.getCurrent()->blockUser(
this->userId_, this,
[this, reenableBlockCheckbox, currentUser] {
Expand All @@ -663,15 +663,75 @@ void UserInfoPopup::installEvents()
},
[this, reenableBlockCheckbox] {
this->channel_->addSystemMessage(
QString(
"User %1 couldn't be blocked, an unknown "
"error occurred!")
QString("User %1 couldn't be blocked, an "
"unknown "
"error occurred!")
.arg(this->userName_));
reenableBlockCheckbox();
});
}
break;
};
getHelix()->getFollowedChannel(
getApp()->getAccounts()->twitch.getCurrent()->getUserId(),
this->userId_, this,
[this, blockThisUser,
reenableBlockCheckbox](const auto &followStatus) {
if (!followStatus)
{
blockThisUser();
return;
}
bool wasPinned = this->ensurePinned();
auto btn = QMessageBox::warning(
this, u"Blocking " % this->userName_,
u"You're following %1 since %2.\n"_s
"Blocking %1 will unfollow them!\n\n"
"Are you sure you want to unfollow and block %1?"
.arg(this->userName_,
followStatus->followedAt.toString()),
QMessageBox::Yes | QMessageBox::Cancel,
QMessageBox::Cancel);
if (wasPinned)
{
this->togglePinned();
}
if (btn != QMessageBox::Yes)
{
reenableBlockCheckbox();
return;
}
blockThisUser();
},
[this, blockThisUser,
reenableBlockCheckbox](const auto &error) {
bool wasPinned = this->ensurePinned();
auto btn = QMessageBox::warning(
this, u"Blocking " % this->userName_,
u"Failed to get following status for %1 (error: %2).\n"_s
"Blocking a followed channel will automatically "
"unfollow them.\n\n"
"Are you sure you want to block %1?".arg(
this->userName_, error),
QMessageBox::Yes | QMessageBox::Cancel,
QMessageBox::Cancel);
if (wasPinned)
{
this->togglePinned();
}
if (btn == QMessageBox::Yes)
{
blockThisUser();
}
else
{
reenableBlockCheckbox();
}
});
return;
}

qCWarning(chatterinoWidget)
<< "Unexpected check-state when blocking" << this->userName_
<< QMetaEnum::fromType<Qt::CheckState>().valueToKey(newState);
});

// ignore highlights
Expand Down

0 comments on commit 619338c

Please sign in to comment.