mirror of
https://github.com/thelounge/thelounge
synced 2024-11-22 12:03:11 +00:00
Merge pull request #1266 from thelounge/yamanickill/1228-theme-management
Allow themes from npm
This commit is contained in:
commit
2e2e201784
5 changed files with 116 additions and 13 deletions
|
@ -264,8 +264,8 @@
|
|||
<label for="theme-select" class="sr-only">Theme</label>
|
||||
<select id="theme-select" name="theme" class="input">
|
||||
{{#each themes}}
|
||||
<option value="{{filename}}">
|
||||
{{name}}
|
||||
<option value="{{name}}">
|
||||
{{displayName}}
|
||||
</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
|
|
|
@ -51,11 +51,12 @@ module.exports = {
|
|||
|
||||
//
|
||||
// Set the default theme.
|
||||
// Find out how to add new themes at https://thelounge.github.io/docs/packages/themes
|
||||
//
|
||||
// @type string
|
||||
// @default "themes/example.css"
|
||||
// @default "example"
|
||||
//
|
||||
theme: "themes/example.css",
|
||||
theme: "example",
|
||||
|
||||
//
|
||||
// Prefetch URLs
|
||||
|
|
|
@ -12,6 +12,8 @@ const colors = require("colors/safe");
|
|||
var Helper = {
|
||||
config: null,
|
||||
expandHome: expandHome,
|
||||
getPackagesPath: getPackagesPath,
|
||||
getPackageModulePath: getPackageModulePath,
|
||||
getStoragePath: getStoragePath,
|
||||
getUserConfigPath: getUserConfigPath,
|
||||
getUserLogsPath: getUserLogsPath,
|
||||
|
@ -96,6 +98,14 @@ function getStoragePath() {
|
|||
return path.join(this.HOME, "storage");
|
||||
}
|
||||
|
||||
function getPackagesPath() {
|
||||
return path.join(this.HOME, "packages", "node_modules");
|
||||
}
|
||||
|
||||
function getPackageModulePath(packageName) {
|
||||
return path.join(Helper.getPackagesPath(), packageName);
|
||||
}
|
||||
|
||||
function ip2hex(address) {
|
||||
// no ipv6 support
|
||||
if (!net.isIPv4(address)) {
|
||||
|
|
85
src/plugins/themes.js
Normal file
85
src/plugins/themes.js
Normal file
|
@ -0,0 +1,85 @@
|
|||
"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("client/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, "..", "client", "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.lounge) {
|
||||
log.warn(`Specified theme ${colors.yellow(packageName)} doesn't have required information.`);
|
||||
return;
|
||||
}
|
||||
return module.lounge;
|
||||
}
|
||||
|
||||
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
|
||||
};
|
||||
}
|
|
@ -14,6 +14,7 @@ var Helper = require("./helper");
|
|||
var colors = require("colors/safe");
|
||||
const net = require("net");
|
||||
const Identification = require("./identification");
|
||||
const themes = require("./plugins/themes");
|
||||
|
||||
// The order defined the priority: the first available plugin is used
|
||||
// ALways keep local auth in the end, which should always be enabled.
|
||||
|
@ -51,6 +52,15 @@ module.exports = function() {
|
|||
.set("view engine", "html")
|
||||
.set("views", path.join(__dirname, "..", "client"));
|
||||
|
||||
app.get("/themes/:theme.css", (req, res) => {
|
||||
const themeName = req.params.theme;
|
||||
const theme = themes.getFilename(themeName);
|
||||
if (theme === undefined) {
|
||||
return res.status(404).send("Not found");
|
||||
}
|
||||
return res.sendFile(theme);
|
||||
});
|
||||
|
||||
var config = Helper.config;
|
||||
var server = null;
|
||||
|
||||
|
@ -191,16 +201,13 @@ function index(req, res, next) {
|
|||
pkg,
|
||||
Helper.config
|
||||
);
|
||||
if (!data.theme.includes(".css")) { // Backwards compatibility for old way of specifying themes in settings
|
||||
data.theme = `themes/${data.theme}.css`;
|
||||
} else {
|
||||
log.warn(`Referring to CSS files in the ${colors.green("theme")} setting of ${colors.green(Helper.CONFIG_PATH)} is ${colors.bold("deprecated")} and will be removed in a future version.`);
|
||||
}
|
||||
data.gitCommit = Helper.getGitCommit();
|
||||
data.themes = fs.readdirSync("client/themes/").filter(function(themeFile) {
|
||||
return themeFile.endsWith(".css");
|
||||
}).map(function(css) {
|
||||
const filename = css.slice(0, -4);
|
||||
return {
|
||||
name: filename.charAt(0).toUpperCase() + filename.slice(1),
|
||||
filename: filename
|
||||
};
|
||||
});
|
||||
data.themes = themes.getAll();
|
||||
|
||||
const policies = [
|
||||
"default-src *",
|
||||
|
|
Loading…
Reference in a new issue