Implement /ignore and /unignore commands
Simplify authorized network requests for Twitch V5 api add onShow virtual function to settings pages if they need to be refreshed when shown Actually ignoring messages from ignored users is still not implemented Working on #247
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
#include "providers/twitch/twitchaccount.hpp"
|
||||
|
||||
#include "const.hpp"
|
||||
#include "debug/log.hpp"
|
||||
#include "util/networkrequest.hpp"
|
||||
#include "util/urlfetch.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
namespace providers {
|
||||
@@ -68,6 +72,146 @@ bool TwitchAccount::isAnon() const
|
||||
return this->_isAnon;
|
||||
}
|
||||
|
||||
void TwitchAccount::loadIgnores()
|
||||
{
|
||||
QString url("https://api.twitch.tv/kraken/users/" + this->getUserId() + "/blocks");
|
||||
|
||||
util::NetworkRequest req(url);
|
||||
req.setRequestType(util::NetworkRequest::GET);
|
||||
req.setCaller(QThread::currentThread());
|
||||
req.makeAuthorizedV5(this->getOAuthClient(), this->getOAuthToken());
|
||||
req.onSuccess([=](const rapidjson::Document &document) {
|
||||
if (!document.IsObject()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto blocksIt = document.FindMember("blocks");
|
||||
if (blocksIt == document.MemberEnd()) {
|
||||
return false;
|
||||
}
|
||||
const auto &blocks = blocksIt->value;
|
||||
|
||||
if (!blocks.IsArray()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(this->ignoresMutex);
|
||||
this->ignores.clear();
|
||||
|
||||
for (const auto &block : blocks.GetArray()) {
|
||||
if (!block.IsObject()) {
|
||||
continue;
|
||||
}
|
||||
auto userIt = block.FindMember("user");
|
||||
if (userIt == block.MemberEnd()) {
|
||||
continue;
|
||||
}
|
||||
this->ignores.insert(TwitchUser::fromJSON(userIt->value));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
req.execute();
|
||||
}
|
||||
|
||||
void TwitchAccount::ignore(const QString &targetName,
|
||||
std::function<void(const QString &message)> onFinished)
|
||||
{
|
||||
util::twitch::getUserID(targetName, QThread::currentThread(), [=](QString targetUserID) {
|
||||
QString url("https://api.twitch.tv/kraken/users/" + this->getUserId() + "/blocks/" +
|
||||
targetUserID);
|
||||
|
||||
util::NetworkRequest req(url);
|
||||
req.setRequestType(util::NetworkRequest::PUT);
|
||||
req.setCaller(QThread::currentThread());
|
||||
req.makeAuthorizedV5(this->getOAuthClient(), this->getOAuthToken());
|
||||
|
||||
req.onError([=](int errorCode) {
|
||||
onFinished("An unknown error occured while trying to ignore user " + targetName + " (" +
|
||||
QString::number(errorCode) + ")");
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
req.onSuccess([=](const rapidjson::Document &document) {
|
||||
if (!document.IsObject()) {
|
||||
onFinished("Bad JSON data while ignoring user " + targetName);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto userIt = document.FindMember("user");
|
||||
if (userIt == document.MemberEnd()) {
|
||||
onFinished("Bad JSON data while ignoring user (missing user) " + targetName);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto ignoredUser = TwitchUser::fromJSON(userIt->value);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(this->ignoresMutex);
|
||||
|
||||
auto res = this->ignores.insert(ignoredUser);
|
||||
if (!res.second) {
|
||||
const TwitchUser &existingUser = *(res.first);
|
||||
existingUser.update(ignoredUser);
|
||||
onFinished("User " + targetName + " is already ignored");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
onFinished("Successfully ignored user " + targetName);
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
req.execute();
|
||||
});
|
||||
}
|
||||
|
||||
void TwitchAccount::unignore(const QString &targetName,
|
||||
std::function<void(const QString &message)> onFinished)
|
||||
{
|
||||
util::twitch::getUserID(targetName, QThread::currentThread(), [=](QString targetUserID) {
|
||||
QString url("https://api.twitch.tv/kraken/users/" + this->getUserId() + "/blocks/" +
|
||||
targetUserID);
|
||||
|
||||
util::NetworkRequest req(url);
|
||||
req.setRequestType(util::NetworkRequest::DELETE);
|
||||
req.setCaller(QThread::currentThread());
|
||||
req.makeAuthorizedV5(this->getOAuthClient(), this->getOAuthToken());
|
||||
|
||||
req.onError([=](int errorCode) {
|
||||
onFinished("An unknown error occured while trying to unignore user " + targetName +
|
||||
" (" + QString::number(errorCode) + ")");
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
req.onSuccess([=](const rapidjson::Document &document) {
|
||||
TwitchUser ignoredUser;
|
||||
ignoredUser.id = targetUserID;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(this->ignoresMutex);
|
||||
|
||||
this->ignores.erase(ignoredUser);
|
||||
}
|
||||
onFinished("Successfully unignored user " + targetName);
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
req.execute();
|
||||
});
|
||||
}
|
||||
|
||||
std::set<TwitchUser> TwitchAccount::getIgnores() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(this->ignoresMutex);
|
||||
|
||||
return this->ignores;
|
||||
}
|
||||
|
||||
} // namespace twitch
|
||||
} // namespace providers
|
||||
} // namespace chatterino
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "controllers/accounts/account.hpp"
|
||||
#include "providers/twitch/twitchuser.hpp"
|
||||
|
||||
#include <QColor>
|
||||
#include <QString>
|
||||
|
||||
#include "controllers/accounts/account.hpp"
|
||||
#include <set>
|
||||
|
||||
namespace chatterino {
|
||||
namespace providers {
|
||||
@@ -33,6 +36,12 @@ public:
|
||||
|
||||
bool isAnon() const;
|
||||
|
||||
void loadIgnores();
|
||||
void ignore(const QString &targetName, std::function<void(const QString &)> onFinished);
|
||||
void unignore(const QString &targetName, std::function<void(const QString &)> onFinished);
|
||||
|
||||
std::set<TwitchUser> getIgnores() const;
|
||||
|
||||
QColor color;
|
||||
|
||||
private:
|
||||
@@ -41,6 +50,9 @@ private:
|
||||
QString userName;
|
||||
QString userId;
|
||||
const bool _isAnon;
|
||||
|
||||
mutable std::mutex ignoresMutex;
|
||||
std::set<TwitchUser> ignores;
|
||||
};
|
||||
|
||||
} // namespace twitch
|
||||
|
||||
@@ -11,6 +11,10 @@ namespace twitch {
|
||||
TwitchAccountManager::TwitchAccountManager()
|
||||
: anonymousUser(new TwitchAccount(ANONYMOUS_USERNAME, "", "", ""))
|
||||
{
|
||||
this->currentUserChanged.connect([this] {
|
||||
auto currentUser = this->getCurrent();
|
||||
currentUser->loadIgnores();
|
||||
});
|
||||
}
|
||||
|
||||
std::shared_ptr<TwitchAccount> TwitchAccountManager::getCurrent()
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
#include "providers/twitch/twitchuser.hpp"
|
||||
|
||||
#include "util/rapidjson-helpers.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
namespace providers {
|
||||
namespace twitch {
|
||||
|
||||
TwitchUser TwitchUser::fromJSON(const rapidjson::Value &value)
|
||||
{
|
||||
TwitchUser user;
|
||||
|
||||
if (!value.IsObject()) {
|
||||
throw std::runtime_error("JSON value is not an object");
|
||||
}
|
||||
|
||||
if (!rj::getSafe(value, "_id", user.id)) {
|
||||
throw std::runtime_error("Missing ID key");
|
||||
}
|
||||
|
||||
if (!rj::getSafe(value, "name", user.name)) {
|
||||
throw std::runtime_error("Missing name key");
|
||||
}
|
||||
|
||||
if (!rj::getSafe(value, "display_name", user.displayName)) {
|
||||
throw std::runtime_error("Missing display name key");
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
} // namespace twitch
|
||||
} // namespace providers
|
||||
} // namespace chatterino
|
||||
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include <rapidjson/document.h>
|
||||
#include <QString>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace chatterino {
|
||||
namespace providers {
|
||||
namespace twitch {
|
||||
|
||||
struct TwitchUser {
|
||||
QString id;
|
||||
mutable QString name;
|
||||
mutable QString displayName;
|
||||
|
||||
void update(const TwitchUser &other) const
|
||||
{
|
||||
assert(this->id == other.id);
|
||||
|
||||
this->name = other.name;
|
||||
this->displayName = other.displayName;
|
||||
}
|
||||
|
||||
static TwitchUser fromJSON(const rapidjson::Value &value);
|
||||
|
||||
bool operator<(const TwitchUser &rhs) const
|
||||
{
|
||||
return this->id < rhs.id;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace twitch
|
||||
} // namespace providers
|
||||
} // namespace chatterino
|
||||
Reference in New Issue
Block a user