mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-21 22:24:07 +01:00
More progress on tab-complete
There are missing parts to the "account-based" emotes that needs to be completed before emote completion can be considered done. For now, when I've been testing, I've been manually injecting the oauthClient and oauthToken to the settings file with the `user_subscriptions` scope
This commit is contained in:
parent
e4fc6c25e6
commit
3bf111a091
19 changed files with 212 additions and 69 deletions
|
@ -1,5 +1,7 @@
|
||||||
#include "accountmanager.hpp"
|
#include "accountmanager.hpp"
|
||||||
|
|
||||||
|
#include <pajlada/settings/setting.hpp>
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -25,6 +27,9 @@ AccountManager::AccountManager()
|
||||||
if (!envUsername.isEmpty() && !envOauthToken.isEmpty()) {
|
if (!envUsername.isEmpty() && !envOauthToken.isEmpty()) {
|
||||||
this->addTwitchUser(twitch::TwitchUser(envUsername, envOauthToken, ""));
|
this->addTwitchUser(twitch::TwitchUser(envUsername, envOauthToken, ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pajlada::Settings::Setting<std::string>::set(
|
||||||
|
"/accounts/current/roomID", "11148817", pajlada::Settings::SettingOption::DoNotWriteToJSON);
|
||||||
}
|
}
|
||||||
|
|
||||||
twitch::TwitchUser &AccountManager::getTwitchAnon()
|
twitch::TwitchUser &AccountManager::getTwitchAnon()
|
||||||
|
|
|
@ -9,7 +9,8 @@ namespace chatterino {
|
||||||
// It will create the instances of the major classes, and connect their signals to each other
|
// It will create the instances of the major classes, and connect their signals to each other
|
||||||
|
|
||||||
Application::Application()
|
Application::Application()
|
||||||
: windowManager(this->channelManager, this->colorScheme)
|
: completionManager(this->emoteManager)
|
||||||
|
, windowManager(this->channelManager, this->colorScheme, this->completionManager)
|
||||||
, colorScheme(this->windowManager)
|
, colorScheme(this->windowManager)
|
||||||
, emoteManager(this->windowManager, this->resources)
|
, emoteManager(this->windowManager, this->resources)
|
||||||
, resources(this->emoteManager, this->windowManager)
|
, resources(this->emoteManager, this->windowManager)
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
#include "completionmanager.hpp"
|
#include "completionmanager.hpp"
|
||||||
|
#include "common.hpp"
|
||||||
|
#include "emotemanager.hpp"
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
|
||||||
CompletionManager::CompletionManager()
|
CompletionManager::CompletionManager(EmoteManager &_emoteManager)
|
||||||
|
: emoteManager(_emoteManager)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,11 +13,58 @@ CompletionModel *CompletionManager::createModel(const std::string &channelName)
|
||||||
{
|
{
|
||||||
CompletionModel *ret = new CompletionModel();
|
CompletionModel *ret = new CompletionModel();
|
||||||
|
|
||||||
|
this->updateModel(ret, channelName);
|
||||||
|
|
||||||
|
this->emoteManager.bttvGlobalEmoteCodes.updated.connect([=]() {
|
||||||
|
this->updateModel(ret, channelName); //
|
||||||
|
});
|
||||||
|
|
||||||
|
this->emoteManager.ffzGlobalEmoteCodes.updated.connect([=]() {
|
||||||
|
this->updateModel(ret, channelName); //
|
||||||
|
});
|
||||||
|
|
||||||
|
this->emoteManager.bttvChannelEmoteCodes[channelName].updated.connect([=]() {
|
||||||
|
this->updateModel(ret, channelName); //
|
||||||
|
});
|
||||||
|
|
||||||
|
this->emoteManager.ffzChannelEmoteCodes[channelName].updated.connect([=]() {
|
||||||
|
this->updateModel(ret, channelName); //
|
||||||
|
});
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompletionManager::updateModel(CompletionModel *model, const std::string &channelName)
|
void CompletionManager::updateModel(CompletionModel *model, const std::string &channelName)
|
||||||
{
|
{
|
||||||
|
model->emotes.clear();
|
||||||
|
|
||||||
|
for (const auto &m : this->emoteManager.twitchAccountEmotes) {
|
||||||
|
for (const auto &emoteName : m.second.emoteCodes) {
|
||||||
|
model->emotes.push_back(qS(emoteName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> &bttvGlobalEmoteCodes = this->emoteManager.bttvGlobalEmoteCodes;
|
||||||
|
for (const auto &m : bttvGlobalEmoteCodes) {
|
||||||
|
model->emotes.push_back(qS(m));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> &ffzGlobalEmoteCodes = this->emoteManager.ffzGlobalEmoteCodes;
|
||||||
|
for (const auto &m : ffzGlobalEmoteCodes) {
|
||||||
|
model->emotes.push_back(qS(m));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> &bttvChannelEmoteCodes =
|
||||||
|
this->emoteManager.bttvChannelEmoteCodes[channelName];
|
||||||
|
for (const auto &m : bttvChannelEmoteCodes) {
|
||||||
|
model->emotes.push_back(qS(m));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> &ffzChannelEmoteCodes =
|
||||||
|
this->emoteManager.ffzChannelEmoteCodes[channelName];
|
||||||
|
for (const auto &m : ffzChannelEmoteCodes) {
|
||||||
|
model->emotes.push_back(qS(m));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace chatterino
|
} // namespace chatterino
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractListModel>
|
||||||
|
#include <QVector>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
|
||||||
class CompletionModel : public QAbstractItemModel
|
class EmoteManager;
|
||||||
|
|
||||||
|
class CompletionModel : public QAbstractListModel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual int columnCount(const QModelIndex & /*parent*/) const override
|
virtual int columnCount(const QModelIndex & /*parent*/) const override
|
||||||
|
@ -16,34 +19,27 @@ public:
|
||||||
|
|
||||||
virtual QVariant data(const QModelIndex &index, int role) const override
|
virtual QVariant data(const QModelIndex &index, int role) const override
|
||||||
{
|
{
|
||||||
// TODO: Implement
|
// TODO: Implement more safely
|
||||||
return QVariant();
|
return QVariant(this->emotes.at(index.row()));
|
||||||
}
|
|
||||||
|
|
||||||
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const override
|
|
||||||
{
|
|
||||||
// TODO: Implement
|
|
||||||
return QModelIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual QModelIndex parent(const QModelIndex &child) const override
|
|
||||||
{
|
|
||||||
return QModelIndex();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int rowCount(const QModelIndex &parent) const override
|
virtual int rowCount(const QModelIndex &parent) const override
|
||||||
{
|
{
|
||||||
return 1;
|
return this->emotes.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVector<QString> emotes;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CompletionManager
|
class CompletionManager
|
||||||
{
|
{
|
||||||
CompletionManager();
|
CompletionManager(EmoteManager &_emoteManager);
|
||||||
|
|
||||||
|
EmoteManager &emoteManager;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CompletionModel *createModel(const std::string &channelName);
|
CompletionModel *createModel(const std::string &channelName);
|
||||||
void updateModel(CompletionModel *model, const std::string &channelName);
|
void updateModel(CompletionModel *model, const std::string &channelName = std::string());
|
||||||
|
|
||||||
friend class Application;
|
friend class Application;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "emotemanager.hpp"
|
#include "emotemanager.hpp"
|
||||||
|
#include "common.hpp"
|
||||||
#include "resources.hpp"
|
#include "resources.hpp"
|
||||||
#include "util/urlfetch.hpp"
|
#include "util/urlfetch.hpp"
|
||||||
#include "windowmanager.hpp"
|
#include "windowmanager.hpp"
|
||||||
|
@ -25,6 +26,12 @@ EmoteManager::EmoteManager(WindowManager &_windowManager, Resources &_resources)
|
||||||
, resources(_resources)
|
, resources(_resources)
|
||||||
{
|
{
|
||||||
// Note: Do not use this->resources in ctor
|
// Note: Do not use this->resources in ctor
|
||||||
|
pajlada::Settings::Setting<std::string> roomID(
|
||||||
|
"/accounts/current/roomID", "", pajlada::Settings::SettingOption::DoNotWriteToJSON);
|
||||||
|
|
||||||
|
roomID.getValueChangedSignal().connect([this](const std::string &roomID) {
|
||||||
|
this->refreshTwitchEmotes(roomID); //
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmoteManager::loadGlobalEmotes()
|
void EmoteManager::loadGlobalEmotes()
|
||||||
|
@ -48,6 +55,7 @@ void EmoteManager::reloadBTTVChannelEmotes(const QString &channelName)
|
||||||
|
|
||||||
QString linkTemplate = "https:" + rootNode.value("urlTemplate").toString();
|
QString linkTemplate = "https:" + rootNode.value("urlTemplate").toString();
|
||||||
|
|
||||||
|
std::vector<std::string> codes;
|
||||||
for (const QJsonValue &emoteNode : emotesNode) {
|
for (const QJsonValue &emoteNode : emotesNode) {
|
||||||
QJsonObject emoteObject = emoteNode.toObject();
|
QJsonObject emoteObject = emoteNode.toObject();
|
||||||
|
|
||||||
|
@ -67,7 +75,10 @@ void EmoteManager::reloadBTTVChannelEmotes(const QString &channelName)
|
||||||
|
|
||||||
this->bttvChannelEmotes.insert(code, emote);
|
this->bttvChannelEmotes.insert(code, emote);
|
||||||
channelEmoteMap.insert(code, emote);
|
channelEmoteMap.insert(code, emote);
|
||||||
|
codes.push_back(code.toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->bttvChannelEmoteCodes[channelName.toStdString()] = codes;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,6 +95,7 @@ void EmoteManager::reloadFFZChannelEmotes(const QString &channelName)
|
||||||
|
|
||||||
auto setsNode = rootNode.value("sets").toObject();
|
auto setsNode = rootNode.value("sets").toObject();
|
||||||
|
|
||||||
|
std::vector<std::string> codes;
|
||||||
for (const QJsonValue &setNode : setsNode) {
|
for (const QJsonValue &setNode : setsNode) {
|
||||||
auto emotesNode = setNode.toObject().value("emoticons").toArray();
|
auto emotesNode = setNode.toObject().value("emoticons").toArray();
|
||||||
|
|
||||||
|
@ -105,7 +117,10 @@ void EmoteManager::reloadFFZChannelEmotes(const QString &channelName)
|
||||||
|
|
||||||
this->ffzChannelEmotes.insert(code, emote);
|
this->ffzChannelEmotes.insert(code, emote);
|
||||||
channelEmoteMap.insert(code, emote);
|
channelEmoteMap.insert(code, emote);
|
||||||
|
codes.push_back(code.toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->ffzChannelEmoteCodes[channelName.toStdString()] = codes;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -279,9 +294,61 @@ void EmoteManager::parseEmojis(std::vector<std::tuple<EmoteData, QString>> &pars
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EmoteManager::refreshTwitchEmotes(const std::string &roomID)
|
||||||
|
{
|
||||||
|
std::string oauthClient =
|
||||||
|
pajlada::Settings::Setting<std::string>::get("/accounts/" + roomID + "/oauthClient");
|
||||||
|
std::string oauthToken =
|
||||||
|
pajlada::Settings::Setting<std::string>::get("/accounts/" + roomID + "/oauthToken");
|
||||||
|
|
||||||
|
TwitchAccountEmoteData &emoteData = this->twitchAccountEmotes[roomID];
|
||||||
|
|
||||||
|
if (emoteData.filled) {
|
||||||
|
qDebug() << "Already loaded for room id " << qS(roomID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "Loading emotes for room id " << qS(roomID);
|
||||||
|
|
||||||
|
if (oauthClient.empty() || oauthToken.empty()) {
|
||||||
|
qDebug() << "Missing oauth client/token";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// api:v5
|
||||||
|
QString url("https://api.twitch.tv/kraken/users/" + qS(roomID) +
|
||||||
|
"/emotes?api_version=5&oauth_token=" + qS(oauthToken) +
|
||||||
|
"&client_id=" + qS(oauthClient));
|
||||||
|
|
||||||
|
qDebug() << url;
|
||||||
|
|
||||||
|
util::urlFetchJSONTimeout(
|
||||||
|
url,
|
||||||
|
[=, &emoteData](QJsonObject &root) {
|
||||||
|
emoteData.emoteSets.clear();
|
||||||
|
emoteData.emoteCodes.clear();
|
||||||
|
|
||||||
|
auto emoticonSets = root.value("emoticon_sets").toObject();
|
||||||
|
for (QJsonObject::iterator it = emoticonSets.begin(); it != emoticonSets.end(); ++it) {
|
||||||
|
std::string emoteSetString = it.key().toStdString();
|
||||||
|
QJsonArray emoteSetList = it.value().toArray();
|
||||||
|
|
||||||
|
for (QJsonValue emoteValue : emoteSetList) {
|
||||||
|
QJsonObject emoticon = emoteValue.toObject();
|
||||||
|
std::string id = emoticon["id"].toString().toStdString();
|
||||||
|
std::string code = emoticon["code"].toString().toStdString();
|
||||||
|
emoteData.emoteSets[emoteSetString].push_back({id, code});
|
||||||
|
emoteData.emoteCodes.push_back(code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
emoteData.filled = true;
|
||||||
|
},
|
||||||
|
3000);
|
||||||
|
}
|
||||||
|
|
||||||
void EmoteManager::loadBTTVEmotes()
|
void EmoteManager::loadBTTVEmotes()
|
||||||
{
|
{
|
||||||
// bttv
|
|
||||||
QNetworkAccessManager *manager = new QNetworkAccessManager();
|
QNetworkAccessManager *manager = new QNetworkAccessManager();
|
||||||
|
|
||||||
QUrl url("https://api.betterttv.net/2/emotes");
|
QUrl url("https://api.betterttv.net/2/emotes");
|
||||||
|
@ -299,6 +366,7 @@ void EmoteManager::loadBTTVEmotes()
|
||||||
|
|
||||||
QString linkTemplate = "https:" + root.value("urlTemplate").toString();
|
QString linkTemplate = "https:" + root.value("urlTemplate").toString();
|
||||||
|
|
||||||
|
std::vector<std::string> codes;
|
||||||
for (const QJsonValue &emote : emotes) {
|
for (const QJsonValue &emote : emotes) {
|
||||||
QString id = emote.toObject().value("id").toString();
|
QString id = emote.toObject().value("id").toString();
|
||||||
QString code = emote.toObject().value("code").toString();
|
QString code = emote.toObject().value("code").toString();
|
||||||
|
@ -311,7 +379,10 @@ void EmoteManager::loadBTTVEmotes()
|
||||||
this->bttvGlobalEmotes.insert(
|
this->bttvGlobalEmotes.insert(
|
||||||
code, new LazyLoadedImage(*this, this->windowManager, url, 1, code,
|
code, new LazyLoadedImage(*this, this->windowManager, url, 1, code,
|
||||||
code + "\nGlobal BTTV Emote"));
|
code + "\nGlobal BTTV Emote"));
|
||||||
|
codes.push_back(code.toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->bttvGlobalEmoteCodes = codes;
|
||||||
}
|
}
|
||||||
|
|
||||||
reply->deleteLater();
|
reply->deleteLater();
|
||||||
|
@ -321,7 +392,6 @@ void EmoteManager::loadBTTVEmotes()
|
||||||
|
|
||||||
void EmoteManager::loadFFZEmotes()
|
void EmoteManager::loadFFZEmotes()
|
||||||
{
|
{
|
||||||
// ffz
|
|
||||||
QNetworkAccessManager *manager = new QNetworkAccessManager();
|
QNetworkAccessManager *manager = new QNetworkAccessManager();
|
||||||
|
|
||||||
QUrl url("https://api.frankerfacez.com/v1/set/global");
|
QUrl url("https://api.frankerfacez.com/v1/set/global");
|
||||||
|
@ -337,6 +407,7 @@ void EmoteManager::loadFFZEmotes()
|
||||||
|
|
||||||
auto sets = root.value("sets").toObject();
|
auto sets = root.value("sets").toObject();
|
||||||
|
|
||||||
|
std::vector<std::string> codes;
|
||||||
for (const QJsonValue &set : sets) {
|
for (const QJsonValue &set : sets) {
|
||||||
auto emoticons = set.toObject().value("emoticons").toArray();
|
auto emoticons = set.toObject().value("emoticons").toArray();
|
||||||
|
|
||||||
|
@ -354,7 +425,10 @@ void EmoteManager::loadFFZEmotes()
|
||||||
this->ffzGlobalEmotes.insert(
|
this->ffzGlobalEmotes.insert(
|
||||||
code, new LazyLoadedImage(*this, this->windowManager, url1, 1, code,
|
code, new LazyLoadedImage(*this, this->windowManager, url1, 1, code,
|
||||||
code + "\nGlobal FFZ Emote"));
|
code + "\nGlobal FFZ Emote"));
|
||||||
|
codes.push_back(code.toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->ffzGlobalEmoteCodes = codes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "concurrentmap.hpp"
|
#include "concurrentmap.hpp"
|
||||||
#include "emojis.hpp"
|
#include "emojis.hpp"
|
||||||
#include "messages/lazyloadedimage.hpp"
|
#include "messages/lazyloadedimage.hpp"
|
||||||
|
#include "signalvector.hpp"
|
||||||
#include "twitch/emotevalue.hpp"
|
#include "twitch/emotevalue.hpp"
|
||||||
|
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
|
@ -88,11 +89,26 @@ private:
|
||||||
public:
|
public:
|
||||||
void parseEmojis(std::vector<std::tuple<EmoteData, QString>> &parsedWords, const QString &text);
|
void parseEmojis(std::vector<std::tuple<EmoteData, QString>> &parsedWords, const QString &text);
|
||||||
|
|
||||||
private:
|
|
||||||
/// Twitch emotes
|
/// Twitch emotes
|
||||||
// username emote code
|
void refreshTwitchEmotes(const std::string &roomID);
|
||||||
ConcurrentStdMap<QString, std::vector<QString>> twitchAccountEmotes;
|
|
||||||
|
|
||||||
|
struct TwitchAccountEmoteData {
|
||||||
|
struct TwitchEmote {
|
||||||
|
std::string id;
|
||||||
|
std::string code;
|
||||||
|
};
|
||||||
|
|
||||||
|
// emote set
|
||||||
|
std::map<std::string, std::vector<TwitchEmote>> emoteSets;
|
||||||
|
|
||||||
|
std::vector<std::string> emoteCodes;
|
||||||
|
|
||||||
|
bool filled = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::map<std::string, TwitchAccountEmoteData> twitchAccountEmotes;
|
||||||
|
|
||||||
|
private:
|
||||||
// emote code
|
// emote code
|
||||||
ConcurrentMap<QString, twitch::EmoteValue *> _twitchEmotes;
|
ConcurrentMap<QString, twitch::EmoteValue *> _twitchEmotes;
|
||||||
|
|
||||||
|
@ -105,6 +121,9 @@ private:
|
||||||
public:
|
public:
|
||||||
ConcurrentMap<QString, EmoteMap> bttvChannels;
|
ConcurrentMap<QString, EmoteMap> bttvChannels;
|
||||||
EmoteMap bttvGlobalEmotes;
|
EmoteMap bttvGlobalEmotes;
|
||||||
|
SignalVector<std::string> bttvGlobalEmoteCodes;
|
||||||
|
// roomID
|
||||||
|
std::map<std::string, SignalVector<std::string>> bttvChannelEmoteCodes;
|
||||||
EmoteMap _bttvChannelEmoteFromCaches;
|
EmoteMap _bttvChannelEmoteFromCaches;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -116,6 +135,8 @@ private:
|
||||||
public:
|
public:
|
||||||
ConcurrentMap<QString, EmoteMap> ffzChannels;
|
ConcurrentMap<QString, EmoteMap> ffzChannels;
|
||||||
EmoteMap ffzGlobalEmotes;
|
EmoteMap ffzGlobalEmotes;
|
||||||
|
SignalVector<std::string> ffzGlobalEmoteCodes;
|
||||||
|
std::map<std::string, SignalVector<std::string>> ffzChannelEmoteCodes;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ConcurrentMap<int, EmoteData> _ffzChannelEmoteFromCaches;
|
ConcurrentMap<int, EmoteData> _ffzChannelEmoteFromCaches;
|
||||||
|
|
|
@ -79,8 +79,6 @@ Communi::IrcConnection *IrcManager::createConnection(bool doRead)
|
||||||
this->refreshIgnoredUsers(username, oauthClient, oauthToken);
|
this->refreshIgnoredUsers(username, oauthClient, oauthToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->refreshTwitchEmotes(username, oauthClient, oauthToken);
|
|
||||||
|
|
||||||
if (doRead) {
|
if (doRead) {
|
||||||
connection->sendCommand(
|
connection->sendCommand(
|
||||||
Communi::IrcCommand::createCapability("REQ", "twitch.tv/membership"));
|
Communi::IrcCommand::createCapability("REQ", "twitch.tv/membership"));
|
||||||
|
@ -130,34 +128,6 @@ void IrcManager::refreshIgnoredUsers(const QString &username, const QString &oau
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void IrcManager::refreshTwitchEmotes(const QString &username, const QString &oauthClient,
|
|
||||||
const QString &oauthToken)
|
|
||||||
{
|
|
||||||
QString url("https://api.twitch.tv/kraken/users/" + username +
|
|
||||||
"/emotes?oauth_token=" + oauthToken + "&client_id=" + oauthClient);
|
|
||||||
|
|
||||||
if (true) {
|
|
||||||
util::urlFetchJSONTimeout(
|
|
||||||
url,
|
|
||||||
[=](QJsonObject &root) {
|
|
||||||
// nextLink =
|
|
||||||
// root.value("_links").toObject().value("next").toString();
|
|
||||||
|
|
||||||
auto blocks = root.value("blocks").toArray();
|
|
||||||
|
|
||||||
_twitchBlockedUsersMutex.lock();
|
|
||||||
for (QJsonValue block : blocks) {
|
|
||||||
QJsonObject user = block.toObject().value("user").toObject();
|
|
||||||
// display_name
|
|
||||||
_twitchBlockedUsers.insert(user.value("name").toString().toLower(), true);
|
|
||||||
}
|
|
||||||
_twitchBlockedUsersMutex.unlock();
|
|
||||||
qDebug() << "XD";
|
|
||||||
},
|
|
||||||
3000, &this->networkAccessManager);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void IrcManager::beginConnecting()
|
void IrcManager::beginConnecting()
|
||||||
{
|
{
|
||||||
uint32_t generation = ++this->connectionGeneration;
|
uint32_t generation = ++this->connectionGeneration;
|
||||||
|
@ -305,6 +275,7 @@ void IrcManager::handleRoomStateMessage(Communi::IrcMessage *message)
|
||||||
|
|
||||||
if (iterator != tags.end()) {
|
if (iterator != tags.end()) {
|
||||||
std::string roomID = iterator.value().toString().toStdString();
|
std::string roomID = iterator.value().toString().toStdString();
|
||||||
|
|
||||||
this->resources.loadChannelData(roomID);
|
this->resources.loadChannelData(roomID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,8 +76,6 @@ private:
|
||||||
|
|
||||||
void refreshIgnoredUsers(const QString &username, const QString &oauthClient,
|
void refreshIgnoredUsers(const QString &username, const QString &oauthClient,
|
||||||
const QString &oauthToken);
|
const QString &oauthToken);
|
||||||
void refreshTwitchEmotes(const QString &username, const QString &oauthClient,
|
|
||||||
const QString &oauthToken);
|
|
||||||
|
|
||||||
void beginConnecting();
|
void beginConnecting();
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ static int index = 0;
|
||||||
ChatWidget::ChatWidget(ChannelManager &_channelManager, NotebookPage *parent)
|
ChatWidget::ChatWidget(ChannelManager &_channelManager, NotebookPage *parent)
|
||||||
: BaseWidget(parent)
|
: BaseWidget(parent)
|
||||||
, channelManager(_channelManager)
|
, channelManager(_channelManager)
|
||||||
|
, completionManager(parent->completionManager)
|
||||||
, channel(_channelManager.emptyChannel)
|
, channel(_channelManager.emptyChannel)
|
||||||
, vbox(this)
|
, vbox(this)
|
||||||
, header(this)
|
, header(this)
|
||||||
|
|
|
@ -21,6 +21,7 @@ namespace chatterino {
|
||||||
|
|
||||||
class ChannelManager;
|
class ChannelManager;
|
||||||
class ColorScheme;
|
class ColorScheme;
|
||||||
|
class CompletionManager;
|
||||||
|
|
||||||
namespace widgets {
|
namespace widgets {
|
||||||
|
|
||||||
|
@ -59,9 +60,11 @@ public:
|
||||||
protected:
|
protected:
|
||||||
virtual void paintEvent(QPaintEvent *) override;
|
virtual void paintEvent(QPaintEvent *) override;
|
||||||
|
|
||||||
private:
|
public:
|
||||||
ChannelManager &channelManager;
|
ChannelManager &channelManager;
|
||||||
|
CompletionManager &completionManager;
|
||||||
|
|
||||||
|
private:
|
||||||
void setChannel(std::shared_ptr<Channel> newChannel);
|
void setChannel(std::shared_ptr<Channel> newChannel);
|
||||||
void detachChannel();
|
void detachChannel();
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "widgets/chatwidgetinput.hpp"
|
#include "widgets/chatwidgetinput.hpp"
|
||||||
#include "chatwidget.hpp"
|
#include "chatwidget.hpp"
|
||||||
#include "colorscheme.hpp"
|
#include "colorscheme.hpp"
|
||||||
|
#include "completionmanager.hpp"
|
||||||
#include "ircmanager.hpp"
|
#include "ircmanager.hpp"
|
||||||
#include "settingsmanager.hpp"
|
#include "settingsmanager.hpp"
|
||||||
|
|
||||||
|
@ -45,8 +46,8 @@ ChatWidgetInput::ChatWidgetInput(ChatWidget *_chatWidget)
|
||||||
this->refreshTheme();
|
this->refreshTheme();
|
||||||
this->setMessageLengthVisible(SettingsManager::getInstance().showMessageLength.get());
|
this->setMessageLengthVisible(SettingsManager::getInstance().showMessageLength.get());
|
||||||
|
|
||||||
// TODO: Fill in this QCompleter model using our CompletionManager
|
auto completer = new QCompleter(
|
||||||
auto completer = new QCompleter();
|
this->chatWidget->completionManager.createModel(this->chatWidget->channelName));
|
||||||
|
|
||||||
this->textInput.setCompleter(completer);
|
this->textInput.setCompleter(completer);
|
||||||
|
|
||||||
|
|
|
@ -19,10 +19,12 @@
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
namespace widgets {
|
namespace widgets {
|
||||||
|
|
||||||
MainWindow::MainWindow(ChannelManager &_channelManager, ColorScheme &_colorScheme)
|
MainWindow::MainWindow(ChannelManager &_channelManager, ColorScheme &_colorScheme,
|
||||||
|
CompletionManager &_completionManager)
|
||||||
: BaseWidget(_colorScheme, nullptr)
|
: BaseWidget(_colorScheme, nullptr)
|
||||||
, channelManager(_channelManager)
|
, channelManager(_channelManager)
|
||||||
, colorScheme(_colorScheme)
|
, colorScheme(_colorScheme)
|
||||||
|
, completionManager(_completionManager)
|
||||||
, notebook(this->channelManager, this)
|
, notebook(this->channelManager, this)
|
||||||
, windowGeometry("/windows/0/geometry")
|
, windowGeometry("/windows/0/geometry")
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,6 +17,7 @@ namespace chatterino {
|
||||||
|
|
||||||
class ChannelManager;
|
class ChannelManager;
|
||||||
class ColorScheme;
|
class ColorScheme;
|
||||||
|
class CompletionManager;
|
||||||
|
|
||||||
namespace widgets {
|
namespace widgets {
|
||||||
|
|
||||||
|
@ -25,7 +26,8 @@ class MainWindow : public BaseWidget
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MainWindow(ChannelManager &_channelManager, ColorScheme &_colorScheme);
|
explicit MainWindow(ChannelManager &_channelManager, ColorScheme &_colorScheme,
|
||||||
|
CompletionManager &_completionManager);
|
||||||
~MainWindow();
|
~MainWindow();
|
||||||
|
|
||||||
void layoutVisibleChatWidgets(Channel *channel = nullptr);
|
void layoutVisibleChatWidgets(Channel *channel = nullptr);
|
||||||
|
@ -48,6 +50,7 @@ private:
|
||||||
|
|
||||||
ChannelManager &channelManager;
|
ChannelManager &channelManager;
|
||||||
ColorScheme &colorScheme;
|
ColorScheme &colorScheme;
|
||||||
|
CompletionManager &completionManager;
|
||||||
|
|
||||||
Notebook notebook;
|
Notebook notebook;
|
||||||
bool loaded = false;
|
bool loaded = false;
|
||||||
|
@ -144,6 +147,8 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
pajlada::Settings::Setting<QRectWrapper, QRectWrapper> windowGeometry;
|
pajlada::Settings::Setting<QRectWrapper, QRectWrapper> windowGeometry;
|
||||||
|
|
||||||
|
friend class Notebook;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace widgets
|
} // namespace widgets
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "widgets/notebook.hpp"
|
#include "widgets/notebook.hpp"
|
||||||
#include "colorscheme.hpp"
|
#include "colorscheme.hpp"
|
||||||
|
#include "widgets/mainwindow.hpp"
|
||||||
#include "widgets/notebookbutton.hpp"
|
#include "widgets/notebookbutton.hpp"
|
||||||
#include "widgets/notebookpage.hpp"
|
#include "widgets/notebookpage.hpp"
|
||||||
#include "widgets/notebooktab.hpp"
|
#include "widgets/notebooktab.hpp"
|
||||||
|
@ -18,9 +19,10 @@
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
namespace widgets {
|
namespace widgets {
|
||||||
|
|
||||||
Notebook::Notebook(ChannelManager &_channelManager, BaseWidget *parent)
|
Notebook::Notebook(ChannelManager &_channelManager, MainWindow *parent)
|
||||||
: BaseWidget(parent)
|
: BaseWidget(parent)
|
||||||
, channelManager(_channelManager)
|
, channelManager(_channelManager)
|
||||||
|
, completionManager(parent->completionManager)
|
||||||
, addButton(this)
|
, addButton(this)
|
||||||
, settingsButton(this)
|
, settingsButton(this)
|
||||||
, userButton(this)
|
, userButton(this)
|
||||||
|
|
|
@ -12,10 +12,12 @@
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
|
||||||
class ChannelManager;
|
class ChannelManager;
|
||||||
class ColorScheme;
|
class CompletionManager;
|
||||||
|
|
||||||
namespace widgets {
|
namespace widgets {
|
||||||
|
|
||||||
|
class MainWindow;
|
||||||
|
|
||||||
class Notebook : public BaseWidget
|
class Notebook : public BaseWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -23,7 +25,7 @@ class Notebook : public BaseWidget
|
||||||
public:
|
public:
|
||||||
enum HighlightType { none, highlighted, newMessage };
|
enum HighlightType { none, highlighted, newMessage };
|
||||||
|
|
||||||
explicit Notebook(ChannelManager &_channelManager, BaseWidget *parent);
|
explicit Notebook(ChannelManager &_channelManager, MainWindow *parent);
|
||||||
|
|
||||||
NotebookPage *addPage(bool select = false);
|
NotebookPage *addPage(bool select = false);
|
||||||
|
|
||||||
|
@ -50,9 +52,11 @@ public slots:
|
||||||
void usersButtonClicked();
|
void usersButtonClicked();
|
||||||
void addPageButtonClicked();
|
void addPageButtonClicked();
|
||||||
|
|
||||||
private:
|
public:
|
||||||
ChannelManager &channelManager;
|
ChannelManager &channelManager;
|
||||||
|
CompletionManager &completionManager;
|
||||||
|
|
||||||
|
private:
|
||||||
QList<NotebookPage *> pages;
|
QList<NotebookPage *> pages;
|
||||||
|
|
||||||
NotebookButton addButton;
|
NotebookButton addButton;
|
||||||
|
|
|
@ -25,6 +25,7 @@ std::pair<int, int> NotebookPage::dropPosition = std::pair<int, int>(-1, -1);
|
||||||
NotebookPage::NotebookPage(ChannelManager &_channelManager, Notebook *parent, NotebookTab *_tab)
|
NotebookPage::NotebookPage(ChannelManager &_channelManager, Notebook *parent, NotebookTab *_tab)
|
||||||
: BaseWidget(parent->colorScheme, parent)
|
: BaseWidget(parent->colorScheme, parent)
|
||||||
, channelManager(_channelManager)
|
, channelManager(_channelManager)
|
||||||
|
, completionManager(parent->completionManager)
|
||||||
, tab(_tab)
|
, tab(_tab)
|
||||||
, dropPreview(this)
|
, dropPreview(this)
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
|
||||||
class ChannelManager;
|
class ChannelManager;
|
||||||
|
class CompletionManager;
|
||||||
|
|
||||||
namespace widgets {
|
namespace widgets {
|
||||||
|
|
||||||
|
@ -29,6 +30,7 @@ public:
|
||||||
NotebookPage(ChannelManager &_channelManager, Notebook *parent, NotebookTab *_tab);
|
NotebookPage(ChannelManager &_channelManager, Notebook *parent, NotebookTab *_tab);
|
||||||
|
|
||||||
ChannelManager &channelManager;
|
ChannelManager &channelManager;
|
||||||
|
CompletionManager &completionManager;
|
||||||
|
|
||||||
std::pair<int, int> removeFromLayout(ChatWidget *widget);
|
std::pair<int, int> removeFromLayout(ChatWidget *widget);
|
||||||
void addToLayout(ChatWidget *widget, std::pair<int, int> position);
|
void addToLayout(ChatWidget *widget, std::pair<int, int> position);
|
||||||
|
|
|
@ -10,9 +10,11 @@
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
|
||||||
WindowManager::WindowManager(ChannelManager &_channelManager, ColorScheme &_colorScheme)
|
WindowManager::WindowManager(ChannelManager &_channelManager, ColorScheme &_colorScheme,
|
||||||
|
CompletionManager &_completionManager)
|
||||||
: channelManager(_channelManager)
|
: channelManager(_channelManager)
|
||||||
, colorScheme(_colorScheme)
|
, colorScheme(_colorScheme)
|
||||||
|
, completionManager(_completionManager)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +58,8 @@ widgets::MainWindow &WindowManager::getMainWindow()
|
||||||
std::lock_guard<std::mutex> lock(this->windowMutex);
|
std::lock_guard<std::mutex> lock(this->windowMutex);
|
||||||
|
|
||||||
if (this->mainWindow == nullptr) {
|
if (this->mainWindow == nullptr) {
|
||||||
this->mainWindow = new widgets::MainWindow(this->channelManager, this->colorScheme);
|
this->mainWindow = new widgets::MainWindow(this->channelManager, this->colorScheme,
|
||||||
|
this->completionManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this->mainWindow;
|
return *this->mainWindow;
|
||||||
|
|
|
@ -8,14 +8,17 @@ namespace chatterino {
|
||||||
|
|
||||||
class ChannelManager;
|
class ChannelManager;
|
||||||
class ColorScheme;
|
class ColorScheme;
|
||||||
|
class CompletionManager;
|
||||||
|
|
||||||
class WindowManager
|
class WindowManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit WindowManager(ChannelManager &_channelManager, ColorScheme &_colorScheme);
|
explicit WindowManager(ChannelManager &_channelManager, ColorScheme &_colorScheme,
|
||||||
|
CompletionManager &_completionManager);
|
||||||
|
|
||||||
ChannelManager &channelManager;
|
ChannelManager &channelManager;
|
||||||
ColorScheme &colorScheme;
|
ColorScheme &colorScheme;
|
||||||
|
CompletionManager &completionManager;
|
||||||
|
|
||||||
void layoutVisibleChatWidgets(Channel *channel = nullptr);
|
void layoutVisibleChatWidgets(Channel *channel = nullptr);
|
||||||
void repaintVisibleChatWidgets(Channel *channel = nullptr);
|
void repaintVisibleChatWidgets(Channel *channel = nullptr);
|
||||||
|
|
Loading…
Reference in a new issue