diff --git a/src/server/index.tsx b/src/server/index.tsx index 44f901ca..7eb4e224 100644 --- a/src/server/index.tsx +++ b/src/server/index.tsx @@ -27,40 +27,6 @@ const [hostname, port] = process.env["LEMMY_UI_HOST"] const extraThemesFolder = process.env["LEMMY_UI_EXTRA_THEMES_FOLDER"] || "./extra_themes"; -export const themeList = buildThemeList(); - -export const builtinThemes = [ - "litera", - "materia", - "minty", - "solar", - "united", - "cyborg", - "darkly", - "journal", - "sketchy", - "vaporwave", - "vaporwave-dark", - "i386", - "litely", - "nord", -]; - -function buildThemeList(): string[] { - let data = fs.readdirSync(extraThemesFolder); - if (data != null) { - 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)); - return data; - } else { - return builtinThemes; - } -} - server.use(express.json()); server.use(express.urlencoded({ extended: false })); server.use("/static", express.static(path.resolve("./dist"))); @@ -99,6 +65,38 @@ server.get("/css/themes/:name", async (req, res) => { } }); +function buildThemeList(): string[] { + let themes = [ + "litera", + "materia", + "minty", + "solar", + "united", + "cyborg", + "darkly", + "journal", + "sketchy", + "vaporwave", + "vaporwave-dark", + "i386", + "litely", + "nord", + ]; + let dirThemes = fs.readdirSync(extraThemesFolder); + if (dirThemes != null) { + let minCssThemes = dirThemes + .filter(d => d.endsWith(".min.css")) + .map(d => d.replace(".min.css", "")); + themes.push(...minCssThemes); + } + return themes; +} + +server.get("/css/themelist", async (_req, res) => { + res.type("json"); + res.send(JSON.stringify(buildThemeList())); +}); + // server.use(cookieParser()); server.get("/*", async (req, res) => { try { diff --git a/src/shared/components/person/settings.tsx b/src/shared/components/person/settings.tsx index 0729b369..9e045e4d 100644 --- a/src/shared/components/person/settings.tsx +++ b/src/shared/components/person/settings.tsx @@ -19,7 +19,6 @@ import { } from "lemmy-js-client"; import { Subscription } from "rxjs"; import { i18n, languages } from "../../i18next"; -import { themeList } from "../../../server/index"; import { UserService, WebSocketService } from "../../services"; import { authField, @@ -30,6 +29,7 @@ import { debounce, elementUrl, fetchCommunities, + fetchThemeList, fetchUsers, getLanguages, isBrowser, @@ -78,6 +78,7 @@ interface SettingsState { blockCommunity?: CommunityView; currentTab: string; siteRes: GetSiteResponse; + themeList: string[]; } export class Settings extends Component { @@ -109,6 +110,7 @@ export class Settings extends Component { blockCommunityId: 0, currentTab: "settings", siteRes: this.isoData.site_res, + themeList: [], }; constructor(props: any, context: any) { @@ -131,8 +133,10 @@ export class Settings extends Component { this.setUserInfo(); } - componentDidMount() { + async componentDidMount() { setupTippy(); + this.state.themeList = await fetchThemeList(); + this.setState(this.state); } componentWillUnmount() { @@ -545,7 +549,7 @@ export class Settings extends Component { {i18n.t("theme")} - {themeList.map(theme => ( + {this.state.themeList.map(theme => ( ))} diff --git a/src/shared/utils.ts b/src/shared/utils.ts index c38f3d7a..2278256b 100644 --- a/src/shared/utils.ts +++ b/src/shared/utils.ts @@ -36,7 +36,6 @@ import markdown_it_sup from "markdown-it-sup"; import moment from "moment"; import { Subscription } from "rxjs"; import { delay, retryWhen, take } from "rxjs/operators"; -import { themeList } from "server"; import tippy from "tippy.js"; import Toastify from "toastify-js"; import { httpBase } from "./env"; @@ -349,7 +348,11 @@ function getBrowserLanguages(): string[] { return allowedLangs; } -export function setTheme(theme: string, forceReload = false) { +export async function fetchThemeList(): Promise { + return fetch("/css/themelist").then(res => res.json()); +} + +export async function setTheme(theme: string, forceReload = false) { if (!isBrowser()) { return; } @@ -361,6 +364,8 @@ export function setTheme(theme: string, forceReload = false) { theme = "darkly"; } + let themeList = await fetchThemeList(); + // Unload all the other themes for (var i = 0; i < themeList.length; i++) { let styleSheet = document.getElementById(themeList[i]); @@ -375,7 +380,8 @@ export function setTheme(theme: string, forceReload = false) { document.getElementById("default-dark")?.setAttribute("disabled", "disabled"); // Load the theme dynamically - let cssLoc = `/static/assets/css/themes/${theme}.min.css`; + let cssLoc = `/css/themes/${theme}.min.css`; + loadCss(theme, cssLoc); document.getElementById(theme).removeAttribute("disabled"); }