mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-21 22:24:07 +01:00
Add a Plugins settings page
This commit is contained in:
parent
cc0aa1aa82
commit
03de6869c4
6 changed files with 128 additions and 14 deletions
|
@ -542,6 +542,8 @@ set(SOURCE_FILES
|
||||||
widgets/settingspages/NicknamesPage.hpp
|
widgets/settingspages/NicknamesPage.hpp
|
||||||
widgets/settingspages/NotificationPage.cpp
|
widgets/settingspages/NotificationPage.cpp
|
||||||
widgets/settingspages/NotificationPage.hpp
|
widgets/settingspages/NotificationPage.hpp
|
||||||
|
widgets/settingspages/PluginsPage.cpp
|
||||||
|
widgets/settingspages/PluginsPage.hpp
|
||||||
widgets/settingspages/SettingsPage.cpp
|
widgets/settingspages/SettingsPage.cpp
|
||||||
widgets/settingspages/SettingsPage.hpp
|
widgets/settingspages/SettingsPage.hpp
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
#include "widgets/splits/Split.hpp"
|
#include "widgets/splits/Split.hpp"
|
||||||
#include "widgets/Window.hpp"
|
#include "widgets/Window.hpp"
|
||||||
|
|
||||||
|
#include <QJsonDocument>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
@ -43,14 +45,32 @@ void PluginController::initialize(Settings &settings, Paths &paths)
|
||||||
<< "Missing index.lua in plugin directory" << pluginDir;
|
<< "Missing index.lua in plugin directory" << pluginDir;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
qCDebug(chatterinoLua) << "found index.lua, running it!";
|
qCDebug(chatterinoLua)
|
||||||
|
<< "found index.lua, now looking for info.json!";
|
||||||
|
auto info = QFileInfo(pluginDir.filePath("info.json"));
|
||||||
|
if (!info.exists())
|
||||||
|
{
|
||||||
|
qCDebug(chatterinoLua)
|
||||||
|
<< "Missing info.json in plugin directory" << pluginDir;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
QFile infoFile(info.absoluteFilePath());
|
||||||
|
infoFile.open(QIODevice::ReadOnly);
|
||||||
|
auto everything = infoFile.readAll();
|
||||||
|
auto doc = QJsonDocument::fromJson(everything);
|
||||||
|
if (!doc.isObject())
|
||||||
|
{
|
||||||
|
qCDebug(chatterinoLua)
|
||||||
|
<< "info.json root is not an object" << pluginDir;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
this->load(index, pluginDir);
|
this->load(index, pluginDir, PluginMeta(doc.object()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PluginController::load(QFileInfo index, QDir pluginDir)
|
void PluginController::load(QFileInfo index, QDir pluginDir, PluginMeta meta)
|
||||||
{
|
{
|
||||||
qCDebug(chatterinoLua) << "Running lua file" << index;
|
qCDebug(chatterinoLua) << "Running lua file" << index;
|
||||||
lua_State *l = luaL_newstate();
|
lua_State *l = luaL_newstate();
|
||||||
|
@ -58,8 +78,8 @@ void PluginController::load(QFileInfo index, QDir pluginDir)
|
||||||
this->loadChatterinoLib(l);
|
this->loadChatterinoLib(l);
|
||||||
|
|
||||||
auto pluginName = pluginDir.dirName();
|
auto pluginName = pluginDir.dirName();
|
||||||
auto plugin = std::make_unique<Plugin>(pluginName, l);
|
auto plugin = std::make_unique<Plugin>(pluginName, l, meta);
|
||||||
this->plugins.insert({pluginName, std::move(plugin)});
|
this->plugins_.insert({pluginName, std::move(plugin)});
|
||||||
|
|
||||||
luaL_dofile(l, index.absoluteFilePath().toStdString().c_str());
|
luaL_dofile(l, index.absoluteFilePath().toStdString().c_str());
|
||||||
qCInfo(chatterinoLua) << "Loaded" << pluginName << "plugin from" << index;
|
qCInfo(chatterinoLua) << "Loaded" << pluginName << "plugin from" << index;
|
||||||
|
@ -67,7 +87,7 @@ void PluginController::load(QFileInfo index, QDir pluginDir)
|
||||||
|
|
||||||
void PluginController::callEvery(const QString &functionName)
|
void PluginController::callEvery(const QString &functionName)
|
||||||
{
|
{
|
||||||
for (const auto &[name, plugin] : this->plugins)
|
for (const auto &[name, plugin] : this->plugins_)
|
||||||
{
|
{
|
||||||
lua_getglobal(plugin->state_, functionName.toStdString().c_str());
|
lua_getglobal(plugin->state_, functionName.toStdString().c_str());
|
||||||
lua_pcall(plugin->state_, 0, 0, 0);
|
lua_pcall(plugin->state_, 0, 0, 0);
|
||||||
|
@ -78,7 +98,7 @@ void PluginController::callEveryWithArgs(
|
||||||
const QString &functionName, int count,
|
const QString &functionName, int count,
|
||||||
std::function<void(const std::unique_ptr<Plugin> &pl, lua_State *L)> argCb)
|
std::function<void(const std::unique_ptr<Plugin> &pl, lua_State *L)> argCb)
|
||||||
{
|
{
|
||||||
for (const auto &[name, plugin] : this->plugins)
|
for (const auto &[name, plugin] : this->plugins_)
|
||||||
{
|
{
|
||||||
lua_getglobal(plugin->state_, functionName.toStdString().c_str());
|
lua_getglobal(plugin->state_, functionName.toStdString().c_str());
|
||||||
argCb(plugin, plugin->state_);
|
argCb(plugin, plugin->state_);
|
||||||
|
@ -89,7 +109,7 @@ void PluginController::callEveryWithArgs(
|
||||||
QString PluginController::tryExecPluginCommand(const QString &commandName,
|
QString PluginController::tryExecPluginCommand(const QString &commandName,
|
||||||
const CommandContext &ctx)
|
const CommandContext &ctx)
|
||||||
{
|
{
|
||||||
for (auto &[name, plugin] : this->plugins)
|
for (auto &[name, plugin] : this->plugins_)
|
||||||
{
|
{
|
||||||
if (auto it = plugin->ownedCommands.find(commandName);
|
if (auto it = plugin->ownedCommands.find(commandName);
|
||||||
it != plugin->ownedCommands.end())
|
it != plugin->ownedCommands.end())
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
@ -20,12 +22,34 @@ struct lua_State;
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
|
||||||
|
struct PluginMeta {
|
||||||
|
QString name;
|
||||||
|
QString description;
|
||||||
|
QString authors;
|
||||||
|
QString homepage;
|
||||||
|
std::vector<QString> tags;
|
||||||
|
|
||||||
|
explicit PluginMeta(const QJsonObject &obj)
|
||||||
|
: name(obj.value("name").toString())
|
||||||
|
, description(obj.value("description").toString())
|
||||||
|
, authors(obj.value("authors").toString())
|
||||||
|
, homepage(obj.value("homepage").toString())
|
||||||
|
{
|
||||||
|
for (const auto &t : obj.value("tags").toArray())
|
||||||
|
{
|
||||||
|
tags.push_back(t.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class Plugin
|
class Plugin
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QString name;
|
QString codename;
|
||||||
Plugin(QString name, lua_State *state)
|
PluginMeta meta;
|
||||||
: name(std::move(name))
|
Plugin(QString codename, lua_State *state, PluginMeta meta)
|
||||||
|
: codename(std::move(codename))
|
||||||
|
, meta(std::move(meta))
|
||||||
, state_(state)
|
, state_(state)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -73,7 +97,7 @@ public:
|
||||||
// This is required to be public because of c functions
|
// This is required to be public because of c functions
|
||||||
Plugin *getPluginByStatePtr(lua_State *L)
|
Plugin *getPluginByStatePtr(lua_State *L)
|
||||||
{
|
{
|
||||||
for (auto &[name, plugin] : this->plugins)
|
for (auto &[name, plugin] : this->plugins_)
|
||||||
{
|
{
|
||||||
if (plugin->state_ == L)
|
if (plugin->state_ == L)
|
||||||
{
|
{
|
||||||
|
@ -83,10 +107,15 @@ public:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::map<QString, std::unique_ptr<Plugin>> &plugins() const
|
||||||
|
{
|
||||||
|
return this->plugins_;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void load(QFileInfo index, QDir pluginDir);
|
void load(QFileInfo index, QDir pluginDir, PluginMeta meta);
|
||||||
void loadChatterinoLib(lua_State *l);
|
void loadChatterinoLib(lua_State *l);
|
||||||
std::map<QString, std::unique_ptr<Plugin>> plugins;
|
std::map<QString, std::unique_ptr<Plugin>> plugins_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}; // namespace chatterino
|
}; // namespace chatterino
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "widgets/settingspages/ModerationPage.hpp"
|
#include "widgets/settingspages/ModerationPage.hpp"
|
||||||
#include "widgets/settingspages/NicknamesPage.hpp"
|
#include "widgets/settingspages/NicknamesPage.hpp"
|
||||||
#include "widgets/settingspages/NotificationPage.hpp"
|
#include "widgets/settingspages/NotificationPage.hpp"
|
||||||
|
#include "widgets/settingspages/PluginsPage.hpp"
|
||||||
|
|
||||||
#include <QDialogButtonBox>
|
#include <QDialogButtonBox>
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
|
@ -215,6 +216,7 @@ void SettingsDialog::addTabs()
|
||||||
this->addTab([]{return new ModerationPage;}, "Moderation", ":/settings/moderation.svg", SettingsTabId::Moderation);
|
this->addTab([]{return new ModerationPage;}, "Moderation", ":/settings/moderation.svg", SettingsTabId::Moderation);
|
||||||
this->addTab([]{return new NotificationPage;}, "Live Notifications", ":/settings/notification2.svg");
|
this->addTab([]{return new NotificationPage;}, "Live Notifications", ":/settings/notification2.svg");
|
||||||
this->addTab([]{return new ExternalToolsPage;}, "External tools", ":/settings/externaltools.svg");
|
this->addTab([]{return new ExternalToolsPage;}, "External tools", ":/settings/externaltools.svg");
|
||||||
|
this->addTab([]{return new PluginsPage;}, "Plugins", ":/settings/externaltools.svg");
|
||||||
this->ui_.tabContainer->addStretch(1);
|
this->ui_.tabContainer->addStretch(1);
|
||||||
this->addTab([]{return new AboutPage;}, "About", ":/settings/about.svg", SettingsTabId(), Qt::AlignBottom);
|
this->addTab([]{return new AboutPage;}, "About", ":/settings/about.svg", SettingsTabId(), Qt::AlignBottom);
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
52
src/widgets/settingspages/PluginsPage.cpp
Normal file
52
src/widgets/settingspages/PluginsPage.cpp
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
#include "PluginsPage.hpp"
|
||||||
|
|
||||||
|
#include "Application.hpp"
|
||||||
|
#include "controllers/plugins/PluginController.hpp"
|
||||||
|
#include "singletons/Settings.hpp"
|
||||||
|
#include "util/Helpers.hpp"
|
||||||
|
#include "util/LayoutCreator.hpp"
|
||||||
|
#include "util/RemoveScrollAreaBackground.hpp"
|
||||||
|
|
||||||
|
#include <QFormLayout>
|
||||||
|
#include <QGroupBox>
|
||||||
|
#include <QLabel>
|
||||||
|
|
||||||
|
namespace chatterino {
|
||||||
|
|
||||||
|
PluginsPage::PluginsPage()
|
||||||
|
{
|
||||||
|
LayoutCreator<PluginsPage> layoutCreator(this);
|
||||||
|
|
||||||
|
auto scroll = layoutCreator.emplace<QScrollArea>();
|
||||||
|
auto widget = scroll.emplaceScrollAreaWidget();
|
||||||
|
removeScrollAreaBackground(scroll.getElement(), widget.getElement());
|
||||||
|
|
||||||
|
auto layout = widget.setLayoutType<QVBoxLayout>();
|
||||||
|
auto group = layout.emplace<QGroupBox>("Plugins");
|
||||||
|
auto groupLayout = group.setLayoutType<QFormLayout>();
|
||||||
|
|
||||||
|
auto *description =
|
||||||
|
new QLabel("You can load plugins by putting them into "
|
||||||
|
"<chatterino-app-data-folder>/Plugins/. Each one is a "
|
||||||
|
"new directory.");
|
||||||
|
description->setWordWrap(true);
|
||||||
|
description->setStyleSheet("color: #bbb");
|
||||||
|
groupLayout->addRow(description);
|
||||||
|
|
||||||
|
for (const auto &[codename, plugin] : getApp()->plugins->plugins())
|
||||||
|
{
|
||||||
|
auto plgroup = groupLayout.emplace<QGroupBox>(plugin->meta.name);
|
||||||
|
auto pl = plgroup.setLayoutType<QFormLayout>();
|
||||||
|
auto *descrText = new QLabel(plugin->meta.description);
|
||||||
|
descrText->setTextFormat(Qt::TextFormat::MarkdownText);
|
||||||
|
descrText->setWordWrap(true);
|
||||||
|
descrText->setStyleSheet("color: #bbb");
|
||||||
|
pl->addRow(descrText);
|
||||||
|
pl->addRow("Authors", new QLabel(plugin->meta.authors));
|
||||||
|
auto *homepage = new QLabel(formatRichLink(plugin->meta.homepage));
|
||||||
|
homepage->setOpenExternalLinks(true);
|
||||||
|
|
||||||
|
pl->addRow("Homepage", homepage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace chatterino
|
9
src/widgets/settingspages/PluginsPage.hpp
Normal file
9
src/widgets/settingspages/PluginsPage.hpp
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#pragma once
|
||||||
|
#include "widgets/settingspages/SettingsPage.hpp"
|
||||||
|
namespace chatterino {
|
||||||
|
class PluginsPage : public SettingsPage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PluginsPage();
|
||||||
|
};
|
||||||
|
} // namespace chatterino
|
Loading…
Reference in a new issue