wip: support custom themes

This commit is contained in:
Felix Ableitner 2022-02-16 12:49:00 +01:00
parent 99f652422f
commit 904d33e895
3 changed files with 83 additions and 19 deletions

View file

@ -1,4 +1,5 @@
import express from "express";
import fs from "fs";
import { IncomingHttpHeaders } from "http";
import { Helmet } from "inferno-helmet";
import { matchPath, StaticRouter } from "inferno-router";
@ -23,6 +24,8 @@ const server = express();
const [hostname, port] = process.env["LEMMY_UI_HOST"]
? process.env["LEMMY_UI_HOST"].split(":")
: ["0.0.0.0", "1234"];
const extraThemesFolder =
process.env["LEMMY_UI_EXTRA_THEMES_FOLDER"] || "./extra_themes";
server.use(express.json());
server.use(express.urlencoded({ extended: false }));
@ -46,6 +49,64 @@ server.get("/robots.txt", async (_req, res) => {
res.send(robotstxt);
});
server.get("/css/themes-list", async (req, res) => {
const builtinThemes = [
"litera",
"materia",
"minty",
"solar",
"united",
"cyborg",
"darkly",
"journal",
"sketchy",
"vaporwave",
"vaporwave-dark",
"i386",
"litely",
"nord",
];
fs.readdir(extraThemesFolder, function (err, data) {
data = data
.filter(d => d.endsWith(".min.css"))
.map(d => d.replace(".min.css", ""));
data = builtinThemes.concat(data);
// use set to remove duplicate values
data = Array.from(new Set(data));
res.send(data);
});
});
server.get("/css/themes/:name", async (req, res) => {
const theme = req.params.name;
if (!theme.endsWith(".css")) {
res.send("Theme must be a css file");
}
// try extra themes first
fs.readFile(`${extraThemesFolder}/${theme}`, "utf8", function (err, data) {
if (err) {
// if no match found, fallback to builtin themes
fs.readFile(
`./dist/assets/css/themes/${theme}`,
"utf8",
function (err, data) {
if (err) {
const message = `No theme found for name ${theme}`;
res.send(message);
console.error(message);
return;
}
res.send(data);
return;
}
);
return;
}
res.send(data);
});
});
// server.use(cookieParser());
server.get("/*", async (req, res) => {
try {

View file

@ -17,21 +17,21 @@ export class Theme extends Component<Props> {
<link
rel="stylesheet"
type="text/css"
href={`/static/assets/css/themes/${user.local_user_view.local_user.theme}.min.css`}
href={`css/themes/${user.local_user_view.local_user.theme}.min.css`}
/>
) : (
[
<link
rel="stylesheet"
type="text/css"
href="/static/assets/css/themes/litely.min.css"
href="css/themes/litely.min.css"
id="default-light"
media="(prefers-color-scheme: light)"
/>,
<link
rel="stylesheet"
type="text/css"
href="/static/assets/css/themes/darkly.min.css"
href="css/themes/darkly.min.css"
id="default-dark"
media="(prefers-color-scheme: no-preference), (prefers-color-scheme: dark)"
/>,

View file

@ -166,7 +166,8 @@ export const languages = [
{ code: "lt" },
];
export const themes = [
export function themes() {
const builtinThemes = [
"litera",
"materia",
"minty",
@ -182,6 +183,8 @@ export const themes = [
"litely",
"nord",
];
return builtinThemes;
}
const DEFAULT_ALPHABET =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";