Merge pull request #1619 from thelounge/1447-css-plugin
Allow custom css from plugins
This commit is contained in:
commit
40aadf7c95
@ -11,6 +11,9 @@
|
||||
<link rel="stylesheet" href="css/primer-tooltips.css">
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
<link id="theme" rel="stylesheet" href="<%- theme %>">
|
||||
<% _.forEach(stylesheets, function(css) { %>
|
||||
<link rel="stylesheet" href="/packages/<%- css %>">
|
||||
<% }); %>
|
||||
<style id="user-specified-css"></style>
|
||||
|
||||
<title>The Lounge</title>
|
||||
|
72
src/plugins/packages/index.js
Normal file
72
src/plugins/packages/index.js
Normal file
@ -0,0 +1,72 @@
|
||||
"use strict";
|
||||
|
||||
const fs = require("fs");
|
||||
const colors = require("colors/safe");
|
||||
const Helper = require("../../helper");
|
||||
const themes = require("./themes");
|
||||
const packageMap = new Map();
|
||||
|
||||
const stylesheets = [];
|
||||
|
||||
module.exports = {
|
||||
getStylesheets,
|
||||
getPackage,
|
||||
loadPackages,
|
||||
};
|
||||
|
||||
const packageApis = function(packageName) {
|
||||
return {
|
||||
Stylesheets: {
|
||||
addFile: addStylesheet.bind(this, packageName),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
function addStylesheet(packageName, filename) {
|
||||
stylesheets.push(packageName + "/" + filename);
|
||||
}
|
||||
|
||||
function getStylesheets() {
|
||||
return stylesheets;
|
||||
}
|
||||
|
||||
function getPackage(name) {
|
||||
return packageMap.get(name);
|
||||
}
|
||||
|
||||
function loadPackages() {
|
||||
fs.readdir(Helper.getPackagesPath(), (err, packages) => {
|
||||
if (err) {
|
||||
return;
|
||||
}
|
||||
packages.forEach((packageName) => {
|
||||
const packageFile = getModuleInfo(packageName);
|
||||
if (!packageFile) {
|
||||
return;
|
||||
}
|
||||
packageMap.set(packageName, packageFile);
|
||||
if (packageFile.type === "theme") {
|
||||
themes.addTheme(packageName, packageFile);
|
||||
}
|
||||
|
||||
if (packageFile.onServerStart) {
|
||||
packageFile.onServerStart(packageApis(packageName));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getModuleInfo(packageName) {
|
||||
let module;
|
||||
try {
|
||||
module = require(Helper.getPackageModulePath(packageName));
|
||||
} catch (e) {
|
||||
log.warn(`Specified package ${colors.yellow(packageName)} is not installed in packages directory`);
|
||||
return;
|
||||
}
|
||||
if (!module.thelounge) {
|
||||
log.warn(`Specified package ${colors.yellow(packageName)} doesn't have required information.`);
|
||||
return;
|
||||
}
|
||||
return module.thelounge;
|
||||
}
|
66
src/plugins/packages/themes.js
Normal file
66
src/plugins/packages/themes.js
Normal file
@ -0,0 +1,66 @@
|
||||
"use strict";
|
||||
|
||||
const fs = require("fs");
|
||||
const Helper = require("../../helper");
|
||||
const path = require("path");
|
||||
const _ = require("lodash");
|
||||
const themes = new Map();
|
||||
|
||||
module.exports = {
|
||||
addTheme,
|
||||
getAll,
|
||||
getFilename,
|
||||
loadLocalThemes,
|
||||
};
|
||||
|
||||
function loadLocalThemes() {
|
||||
fs.readdir(path.join(__dirname, "..", "..", "public", "themes"), (err, builtInThemes) => {
|
||||
if (err) {
|
||||
return;
|
||||
}
|
||||
builtInThemes
|
||||
.filter((theme) => theme.endsWith(".css"))
|
||||
.map(makeLocalThemeObject)
|
||||
.forEach((theme) => themes.set(theme.name, theme));
|
||||
});
|
||||
}
|
||||
|
||||
function addTheme(packageName, packageObject) {
|
||||
const theme = makePackageThemeObject(packageName, packageObject);
|
||||
if (theme) {
|
||||
themes.set(theme.name, theme);
|
||||
}
|
||||
}
|
||||
|
||||
function getAll() {
|
||||
return _.sortBy(Array.from(themes.values()), "displayName");
|
||||
}
|
||||
|
||||
function getFilename(module) {
|
||||
if (themes.has(module)) {
|
||||
return themes.get(module).filename;
|
||||
}
|
||||
}
|
||||
|
||||
function makeLocalThemeObject(css) {
|
||||
const themeName = css.slice(0, -4);
|
||||
return {
|
||||
displayName: themeName.charAt(0).toUpperCase() + themeName.slice(1),
|
||||
filename: path.join(__dirname, "..", "..", "public", "themes", `${themeName}.css`),
|
||||
name: themeName,
|
||||
};
|
||||
}
|
||||
|
||||
function makePackageThemeObject(moduleName, module) {
|
||||
if (!module || module.type !== "theme") {
|
||||
return;
|
||||
}
|
||||
const modulePath = Helper.getPackageModulePath(moduleName);
|
||||
const displayName = module.name || moduleName;
|
||||
const filename = path.join(modulePath, module.css);
|
||||
return {
|
||||
displayName: displayName,
|
||||
filename: filename,
|
||||
name: moduleName,
|
||||
};
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const fs = require("fs");
|
||||
const Helper = require("../helper");
|
||||
const colors = require("colors/safe");
|
||||
const path = require("path");
|
||||
const _ = require("lodash");
|
||||
const themes = new Map();
|
||||
|
||||
module.exports = {
|
||||
getAll: getAll,
|
||||
getFilename: getFilename,
|
||||
};
|
||||
|
||||
fs.readdir(path.join(__dirname, "..", "..", "public", "themes"), (err, builtInThemes) => {
|
||||
if (err) {
|
||||
return;
|
||||
}
|
||||
builtInThemes
|
||||
.filter((theme) => theme.endsWith(".css"))
|
||||
.map(makeLocalThemeObject)
|
||||
.forEach((theme) => themes.set(theme.name, theme));
|
||||
});
|
||||
|
||||
fs.readdir(Helper.getPackagesPath(), (err, packages) => {
|
||||
if (err) {
|
||||
return;
|
||||
}
|
||||
packages
|
||||
.map(makePackageThemeObject)
|
||||
.forEach((theme) => {
|
||||
if (theme) {
|
||||
themes.set(theme.name, theme);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function getAll() {
|
||||
return _.sortBy(Array.from(themes.values()), "displayName");
|
||||
}
|
||||
|
||||
function getFilename(module) {
|
||||
if (themes.has(module)) {
|
||||
return themes.get(module).filename;
|
||||
}
|
||||
}
|
||||
|
||||
function makeLocalThemeObject(css) {
|
||||
const themeName = css.slice(0, -4);
|
||||
return {
|
||||
displayName: themeName.charAt(0).toUpperCase() + themeName.slice(1),
|
||||
filename: path.join(__dirname, "..", "..", "public", "themes", `${themeName}.css`),
|
||||
name: themeName,
|
||||
};
|
||||
}
|
||||
|
||||
function getModuleInfo(packageName) {
|
||||
let module;
|
||||
try {
|
||||
module = require(Helper.getPackageModulePath(packageName));
|
||||
} catch (e) {
|
||||
log.warn(`Specified theme ${colors.yellow(packageName)} is not installed in packages directory`);
|
||||
return;
|
||||
}
|
||||
if (!module.thelounge) {
|
||||
log.warn(`Specified theme ${colors.yellow(packageName)} doesn't have required information.`);
|
||||
return;
|
||||
}
|
||||
return module.thelounge;
|
||||
}
|
||||
|
||||
function makePackageThemeObject(moduleName) {
|
||||
const module = getModuleInfo(moduleName);
|
||||
if (!module || module.type !== "theme") {
|
||||
return;
|
||||
}
|
||||
const modulePath = Helper.getPackageModulePath(moduleName);
|
||||
const displayName = module.name || moduleName;
|
||||
const filename = path.join(modulePath, module.css);
|
||||
return {
|
||||
displayName: displayName,
|
||||
filename: filename,
|
||||
name: moduleName,
|
||||
};
|
||||
}
|
@ -13,9 +13,14 @@ var Helper = require("./helper");
|
||||
var colors = require("colors/safe");
|
||||
const net = require("net");
|
||||
const Identification = require("./identification");
|
||||
const themes = require("./plugins/themes");
|
||||
const changelog = require("./plugins/changelog");
|
||||
|
||||
const themes = require("./plugins/packages/themes");
|
||||
themes.loadLocalThemes();
|
||||
|
||||
const packages = require("./plugins/packages/index");
|
||||
packages.loadPackages();
|
||||
|
||||
// The order defined the priority: the first available plugin is used
|
||||
// ALways keep local auth in the end, which should always be enabled.
|
||||
const authPlugins = [
|
||||
@ -52,6 +57,17 @@ module.exports = function() {
|
||||
return res.sendFile(theme);
|
||||
});
|
||||
|
||||
app.get("/packages/:package/:filename", (req, res) => {
|
||||
const packageName = req.params.package;
|
||||
const fileName = req.params.filename;
|
||||
const packageFile = packages.getPackage(packageName);
|
||||
if (!packageFile || !packages.getStylesheets().includes(`${packageName}/${fileName}`)) {
|
||||
return res.status(404).send("Not found");
|
||||
}
|
||||
const packagePath = Helper.getPackageModulePath(packageName);
|
||||
return res.sendFile(path.join(packagePath, fileName));
|
||||
});
|
||||
|
||||
var config = Helper.config;
|
||||
var server = null;
|
||||
|
||||
@ -235,7 +251,7 @@ function index(req, res, next) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
res.send(_.template(file)(Helper.config));
|
||||
res.send(_.template(file)(getServerConfiguration()));
|
||||
});
|
||||
}
|
||||
|
||||
@ -492,6 +508,14 @@ function getClientConfiguration() {
|
||||
return config;
|
||||
}
|
||||
|
||||
function getServerConfiguration() {
|
||||
const config = _.clone(Helper.config);
|
||||
|
||||
config.stylesheets = packages.getStylesheets();
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
function performAuthentication(data) {
|
||||
const socket = this;
|
||||
let client;
|
||||
|
Loading…
Reference in New Issue
Block a user