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/NotificationPage.cpp
|
||||
widgets/settingspages/NotificationPage.hpp
|
||||
widgets/settingspages/PluginsPage.cpp
|
||||
widgets/settingspages/PluginsPage.hpp
|
||||
widgets/settingspages/SettingsPage.cpp
|
||||
widgets/settingspages/SettingsPage.hpp
|
||||
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#include "widgets/splits/Split.hpp"
|
||||
#include "widgets/Window.hpp"
|
||||
|
||||
#include <QJsonDocument>
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
|
@ -43,14 +45,32 @@ void PluginController::initialize(Settings &settings, Paths &paths)
|
|||
<< "Missing index.lua in plugin directory" << pluginDir;
|
||||
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;
|
||||
lua_State *l = luaL_newstate();
|
||||
|
@ -58,8 +78,8 @@ void PluginController::load(QFileInfo index, QDir pluginDir)
|
|||
this->loadChatterinoLib(l);
|
||||
|
||||
auto pluginName = pluginDir.dirName();
|
||||
auto plugin = std::make_unique<Plugin>(pluginName, l);
|
||||
this->plugins.insert({pluginName, std::move(plugin)});
|
||||
auto plugin = std::make_unique<Plugin>(pluginName, l, meta);
|
||||
this->plugins_.insert({pluginName, std::move(plugin)});
|
||||
|
||||
luaL_dofile(l, index.absoluteFilePath().toStdString().c_str());
|
||||
qCInfo(chatterinoLua) << "Loaded" << pluginName << "plugin from" << index;
|
||||
|
@ -67,7 +87,7 @@ void PluginController::load(QFileInfo index, QDir pluginDir)
|
|||
|
||||
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_pcall(plugin->state_, 0, 0, 0);
|
||||
|
@ -78,7 +98,7 @@ void PluginController::callEveryWithArgs(
|
|||
const QString &functionName, int count,
|
||||
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());
|
||||
argCb(plugin, plugin->state_);
|
||||
|
@ -89,7 +109,7 @@ void PluginController::callEveryWithArgs(
|
|||
QString PluginController::tryExecPluginCommand(const QString &commandName,
|
||||
const CommandContext &ctx)
|
||||
{
|
||||
for (auto &[name, plugin] : this->plugins)
|
||||
for (auto &[name, plugin] : this->plugins_)
|
||||
{
|
||||
if (auto it = plugin->ownedCommands.find(commandName);
|
||||
it != plugin->ownedCommands.end())
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QString>
|
||||
|
||||
#include <map>
|
||||
|
@ -20,12 +22,34 @@ struct lua_State;
|
|||
|
||||
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
|
||||
{
|
||||
public:
|
||||
QString name;
|
||||
Plugin(QString name, lua_State *state)
|
||||
: name(std::move(name))
|
||||
QString codename;
|
||||
PluginMeta meta;
|
||||
Plugin(QString codename, lua_State *state, PluginMeta meta)
|
||||
: codename(std::move(codename))
|
||||
, meta(std::move(meta))
|
||||
, state_(state)
|
||||
{
|
||||
}
|
||||
|
@ -73,7 +97,7 @@ public:
|
|||
// This is required to be public because of c functions
|
||||
Plugin *getPluginByStatePtr(lua_State *L)
|
||||
{
|
||||
for (auto &[name, plugin] : this->plugins)
|
||||
for (auto &[name, plugin] : this->plugins_)
|
||||
{
|
||||
if (plugin->state_ == L)
|
||||
{
|
||||
|
@ -83,10 +107,15 @@ public:
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
const std::map<QString, std::unique_ptr<Plugin>> &plugins() const
|
||||
{
|
||||
return this->plugins_;
|
||||
}
|
||||
|
||||
private:
|
||||
void load(QFileInfo index, QDir pluginDir);
|
||||
void load(QFileInfo index, QDir pluginDir, PluginMeta meta);
|
||||
void loadChatterinoLib(lua_State *l);
|
||||
std::map<QString, std::unique_ptr<Plugin>> plugins;
|
||||
std::map<QString, std::unique_ptr<Plugin>> plugins_;
|
||||
};
|
||||
|
||||
}; // namespace chatterino
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "widgets/settingspages/ModerationPage.hpp"
|
||||
#include "widgets/settingspages/NicknamesPage.hpp"
|
||||
#include "widgets/settingspages/NotificationPage.hpp"
|
||||
#include "widgets/settingspages/PluginsPage.hpp"
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QLineEdit>
|
||||
|
@ -215,6 +216,7 @@ void SettingsDialog::addTabs()
|
|||
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 ExternalToolsPage;}, "External tools", ":/settings/externaltools.svg");
|
||||
this->addTab([]{return new PluginsPage;}, "Plugins", ":/settings/externaltools.svg");
|
||||
this->ui_.tabContainer->addStretch(1);
|
||||
this->addTab([]{return new AboutPage;}, "About", ":/settings/about.svg", SettingsTabId(), Qt::AlignBottom);
|
||||
// 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