feat: delete messages from context menu (#5956)
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
- Minor: Added the ability to filter on messages by the author's user ID (example: `author.user_id == "22484632"`). (#5862)
|
||||
- Minor: Improved error messaging of the `/clip` command. (#5879)
|
||||
- Minor: Added Linux support for Live Notifications toasts. (#5881)
|
||||
- Minor: Messages can now be deleted from the context menu in a channel. (#5956)
|
||||
- Bugfix: Fixed a potential way to escape the Lua Plugin sandbox. (#5846)
|
||||
- Bugfix: Fixed a crash relating to Lua HTTP. (#5800)
|
||||
- Bugfix: Fixed a crash that could occur on Linux and macOS when clicking "Install" from the update prompt. (#5818)
|
||||
|
||||
@@ -283,7 +283,7 @@ void Channel::replaceMessage(size_t hint, const MessagePtr &message,
|
||||
}
|
||||
}
|
||||
|
||||
void Channel::deleteMessage(QString messageID)
|
||||
void Channel::disableMessage(QString messageID)
|
||||
{
|
||||
auto msg = this->findMessage(messageID);
|
||||
if (msg != nullptr)
|
||||
|
||||
@@ -99,7 +99,7 @@ public:
|
||||
void replaceMessage(size_t index, const MessagePtr &replacement);
|
||||
void replaceMessage(size_t hint, const MessagePtr &message,
|
||||
const MessagePtr &replacement);
|
||||
void deleteMessage(QString messageID);
|
||||
void disableMessage(QString messageID);
|
||||
|
||||
/// Removes all messages from this channel and invokes #messagesCleared
|
||||
void clearMessages();
|
||||
|
||||
@@ -32,58 +32,7 @@ QString deleteMessages(TwitchChannel *twitchChannel, const QString &messageID)
|
||||
return "";
|
||||
}
|
||||
|
||||
getHelix()->deleteChatMessages(
|
||||
twitchChannel->roomId(), user->getUserId(), messageID,
|
||||
[]() {
|
||||
// Success handling, we do nothing: IRC/pubsub-edge will dispatch the correct
|
||||
// events to update state for us.
|
||||
},
|
||||
[twitchChannel, messageID](auto error, auto message) {
|
||||
QString errorMessage = QString("Failed to delete chat messages - ");
|
||||
|
||||
switch (error)
|
||||
{
|
||||
case HelixDeleteChatMessagesError::UserMissingScope: {
|
||||
errorMessage +=
|
||||
"Missing required scope. Re-login with your "
|
||||
"account and try again.";
|
||||
}
|
||||
break;
|
||||
|
||||
case HelixDeleteChatMessagesError::UserNotAuthorized: {
|
||||
errorMessage +=
|
||||
"you don't have permission to perform that action.";
|
||||
}
|
||||
break;
|
||||
|
||||
case HelixDeleteChatMessagesError::MessageUnavailable: {
|
||||
// Override default message prefix to match with IRC message format
|
||||
errorMessage =
|
||||
QString("The message %1 does not exist, was deleted, "
|
||||
"or is too old to be deleted.")
|
||||
.arg(messageID);
|
||||
}
|
||||
break;
|
||||
|
||||
case HelixDeleteChatMessagesError::UserNotAuthenticated: {
|
||||
errorMessage += "you need to re-authenticate.";
|
||||
}
|
||||
break;
|
||||
|
||||
case HelixDeleteChatMessagesError::Forwarded: {
|
||||
errorMessage += message;
|
||||
}
|
||||
break;
|
||||
|
||||
case HelixDeleteChatMessagesError::Unknown:
|
||||
default: {
|
||||
errorMessage += "An unknown error has occurred.";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
twitchChannel->addSystemMessage(errorMessage);
|
||||
});
|
||||
twitchChannel->deleteMessagesAs(messageID, user.get());
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -1897,6 +1897,71 @@ void TwitchChannel::createClip()
|
||||
});
|
||||
}
|
||||
|
||||
void TwitchChannel::deleteMessagesAs(const QString &messageID,
|
||||
TwitchAccount *moderator)
|
||||
{
|
||||
getHelix()->deleteChatMessages(
|
||||
this->roomId(), moderator->getUserId(), messageID,
|
||||
[]() {
|
||||
// Success handling, we do nothing: IRC/pubsub will dispatch the correct
|
||||
// events to update state for us.
|
||||
},
|
||||
[lifetime{this->weak_from_this()}, messageID](auto error,
|
||||
const auto &message) {
|
||||
auto self =
|
||||
std::dynamic_pointer_cast<TwitchChannel>(lifetime.lock());
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QString errorMessage = QString("Failed to delete chat messages - ");
|
||||
|
||||
switch (error)
|
||||
{
|
||||
case HelixDeleteChatMessagesError::UserMissingScope: {
|
||||
errorMessage +=
|
||||
"Missing required scope. Re-login with your "
|
||||
"account and try again.";
|
||||
}
|
||||
break;
|
||||
|
||||
case HelixDeleteChatMessagesError::UserNotAuthorized: {
|
||||
errorMessage +=
|
||||
"you don't have permission to perform that action.";
|
||||
}
|
||||
break;
|
||||
|
||||
case HelixDeleteChatMessagesError::MessageUnavailable: {
|
||||
// Override default message prefix to match with IRC message format
|
||||
errorMessage =
|
||||
QString("The message %1 does not exist, was deleted, "
|
||||
"or is too old to be deleted.")
|
||||
.arg(messageID);
|
||||
}
|
||||
break;
|
||||
|
||||
case HelixDeleteChatMessagesError::UserNotAuthenticated: {
|
||||
errorMessage += "you need to re-authenticate.";
|
||||
}
|
||||
break;
|
||||
|
||||
case HelixDeleteChatMessagesError::Forwarded: {
|
||||
errorMessage += message;
|
||||
}
|
||||
break;
|
||||
|
||||
case HelixDeleteChatMessagesError::Unknown:
|
||||
default: {
|
||||
errorMessage += "An unknown error has occurred.";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
self->addSystemMessage(errorMessage);
|
||||
});
|
||||
}
|
||||
|
||||
std::optional<EmotePtr> TwitchChannel::twitchBadge(const QString &set,
|
||||
const QString &version) const
|
||||
{
|
||||
|
||||
@@ -59,6 +59,7 @@ struct HelixGlobalBadges;
|
||||
using HelixChannelBadges = HelixGlobalBadges;
|
||||
|
||||
class TwitchIrcServer;
|
||||
class TwitchAccount;
|
||||
|
||||
const int MAX_QUEUED_REDEMPTIONS = 16;
|
||||
|
||||
@@ -164,6 +165,12 @@ public:
|
||||
QString getCurrentStreamID() const override;
|
||||
void createClip();
|
||||
|
||||
/// Delete the message with the specified ID as a moderator.
|
||||
///
|
||||
/// If the ID is empty, all messages will be deleted, effectively clearing
|
||||
/// the chat.
|
||||
void deleteMessagesAs(const QString &messageID, TwitchAccount *moderator);
|
||||
|
||||
// Data
|
||||
const QString &subscriptionUrl();
|
||||
const QString &channelUrl();
|
||||
|
||||
@@ -647,7 +647,7 @@ void TwitchIrcServer::initialize()
|
||||
{
|
||||
// Gray out approve/deny button upon "ALLOWED" and "DENIED" statuses
|
||||
// They are versions of automod_message_(denied|approved) but for mods.
|
||||
chan->deleteMessage("automod_" + msg.messageID);
|
||||
chan->disableMessage("automod_" + msg.messageID);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2570,6 +2570,18 @@ void ChannelView::addMessageContextMenuItems(QMenu *menu,
|
||||
}
|
||||
}
|
||||
|
||||
auto *twitchChannel =
|
||||
dynamic_cast<TwitchChannel *>(this->underlyingChannel_.get());
|
||||
if (!layout->getMessage()->id.isEmpty() && twitchChannel &&
|
||||
twitchChannel->hasModRights())
|
||||
{
|
||||
menu->addAction(
|
||||
"&Delete message", [twitchChannel, id = layout->getMessage()->id] {
|
||||
twitchChannel->deleteMessagesAs(
|
||||
id, getApp()->getAccounts()->twitch.getCurrent().get());
|
||||
});
|
||||
}
|
||||
|
||||
bool isSearch = this->context_ == Context::Search;
|
||||
bool isReplyOrUserCard = (this->context_ == Context::ReplyThread ||
|
||||
this->context_ == Context::UserCard) &&
|
||||
|
||||
Reference in New Issue
Block a user