From 63add0376e7771ac53939995812aea9f0db8ff93 Mon Sep 17 00:00:00 2001 From: Nelson Chan Date: Mon, 12 Feb 2024 06:22:41 +0800 Subject: [PATCH] Feat: Impl. server default appearance by injected JSON --- server/server.js | 3 + server/utils/inject-default-appearance.js | 50 ++++ src/components/HorizontalTabHeader.vue | 66 +++++ src/components/settings/Appearance.vue | 251 ++++++------------ .../settings/AppearanceSettings.vue | 164 ++++++++++++ src/mixins/theme.js | 18 ++ src/pages/Settings.vue | 9 + 7 files changed, 391 insertions(+), 170 deletions(-) create mode 100644 server/utils/inject-default-appearance.js create mode 100644 src/components/HorizontalTabHeader.vue create mode 100644 src/components/settings/AppearanceSettings.vue diff --git a/server/server.js b/server/server.js index eeffb063..9728c3b1 100644 --- a/server/server.js +++ b/server/server.js @@ -282,6 +282,9 @@ let needSetup = false; const statusPageRouter = require("./routers/status-page-router"); app.use(statusPageRouter); + const { injectDefaultAppearance } = require("./utils/inject-default-appearance"); + app.use(injectDefaultAppearance); + // Universal Route Handler, must be at the end of all express routes. app.get("*", async (_request, response) => { if (_request.originalUrl.startsWith("/upload/")) { diff --git a/server/utils/inject-default-appearance.js b/server/utils/inject-default-appearance.js new file mode 100644 index 00000000..fcf0847c --- /dev/null +++ b/server/utils/inject-default-appearance.js @@ -0,0 +1,50 @@ +const { Settings } = require("../settings"); +const cheerio = require("cheerio"); +const jsesc = require("jsesc"); +const { log } = require("../../src/util"); + +const injectDefaultAppearance = (req, res, next) => { + + try { + // Intercept send() calls and inject Default Appearance + // https://stackoverflow.com/a/60817116 + const oldSend = res.send; + res.send = async (data) => { + + if (typeof data === "string") { + log.debug("inject-default-appearance", req.method + " " + req.url); + const $ = cheerio.load(data); + + const defaultAppearance = await Settings.get("defaultAppearance"); + if (defaultAppearance) { + const head = $("head"); + + const escapedJSONObject = jsesc(defaultAppearance, { isScriptContext: true }); + + const script = $(` + + `); + + head.append(script); + + data = $.root().html(); + } + } + + res.send = oldSend; // set function back to avoid 'double-send' + return res.send(data); + }; + + next(); + } catch (e) { + + next(e); + } + +}; + +module.exports = { + injectDefaultAppearance +}; diff --git a/src/components/HorizontalTabHeader.vue b/src/components/HorizontalTabHeader.vue new file mode 100644 index 00000000..3857394d --- /dev/null +++ b/src/components/HorizontalTabHeader.vue @@ -0,0 +1,66 @@ + + + + + diff --git a/src/components/settings/Appearance.vue b/src/components/settings/Appearance.vue index a1391d61..04411960 100644 --- a/src/components/settings/Appearance.vue +++ b/src/components/settings/Appearance.vue @@ -1,186 +1,97 @@ diff --git a/src/mixins/theme.js b/src/mixins/theme.js index e1486d5a..a8479cfb 100644 --- a/src/mixins/theme.js +++ b/src/mixins/theme.js @@ -13,6 +13,24 @@ export default { }, mounted() { + if (window.defaultAppearance) { + if (window.defaultAppearance.language) { + localStorage.locale = window.defaultAppearance.language; + } + + if (window.defaultAppearance.theme) { + this.userTheme = window.defaultAppearance.theme; + } + + if (window.defaultAppearance.heartbeatBarTheme) { + this.userHeartbeatBar = window.defaultAppearance.heartbeatBarTheme; + } + + if (window.defaultAppearance.styleElapsedTime) { + this.styleElapsedTime = window.defaultAppearance.styleElapsedTime; + } + } + // Default Light if (! this.userTheme) { this.userTheme = "auto"; diff --git a/src/pages/Settings.vue b/src/pages/Settings.vue index 96bb1fee..40f5304e 100644 --- a/src/pages/Settings.vue +++ b/src/pages/Settings.vue @@ -183,6 +183,15 @@ export default { this.settings.trustProxy = false; } + if (this.settings.defaultAppearance === undefined) { + this.settings.defaultAppearance = { + theme: null, + language: null, + heartbeatBarTheme: null, + styleElapsedTime: null, + }; + } + this.settingsLoaded = true; }); },