添加设置页 (#362)

This commit is contained in:
neveler
2025-12-03 16:13:21 +08:00
committed by GitHub
parent 76862e28a7
commit 5c4d02c89e
20 changed files with 380 additions and 79 deletions
+76
View File
@@ -0,0 +1,76 @@
---
layout: null
---
(function (global) {
var PREFIX = "HMCL_DOCS_SETTINGS_";
var data = {};
var events = {};
var config = /*{%comment%}*/{}/*{%endcomment%}*//**{{'/'}}{{ site.data.settings | jsonify }}/**/;
global.addEventListener("storage", function (event) {
if (!event.key) return;
if (event.key.indexOf(PREFIX) !== 0) return;
var handlers = events[event.key];
if (!handlers) return;
var newValue = event.newValue;
var oldValue = event.oldValue;
if (oldValue === newValue) return;
data[event.key] = newValue;
for (var i = 0; i < handlers.length; i++) {
if (typeof handlers[i] === "function") {
handlers[i](newValue, oldValue);
}
}
});
var settings = {
set: function (key, value) {
if (config[key] === undefined) return;
var strKey = (PREFIX + key).toUpperCase();
var newValue = value + "";
data[strKey] = newValue;
localStorage.setItem(strKey, newValue);
var handlers = events[strKey];
if (!handlers) return;
for (var i = 0; i < handlers.length; i++) {
if (typeof handlers[i] === "function") {
handlers[i](newValue);
}
}
},
get: function (key, defaultValue) {
if (config[key] === undefined) return;
var strKey = (PREFIX + key).toUpperCase();
data.hasOwnProperty(strKey) || (data[strKey] = localStorage.getItem(strKey));
if (typeof defaultValue === "string" && data[strKey] === null) {
return defaultValue;
}
return data[strKey];
},
refresh: function (key) {
if (config[key] === undefined) return;
settings.set(key, settings.get(key, config[key].default));
},
onChange: function (key, handler) {
if (config[key] === undefined) return;
if (typeof handler !== "function") return;
var strKey = (PREFIX + key).toUpperCase();
if (config[key].type === "radio") {
handler(settings.get(key, config[key].default));
}
if (!events[strKey]) {
events[strKey] = [handler];
} else {
events[strKey].push(handler);
}
}
};
global.settings = settings;
})(window);
+70 -45
View File
@@ -1,45 +1,70 @@
---
layout: null
---
var darkTheme = document.createElement("link");
darkTheme.rel = "stylesheet alternate";
darkTheme.href = "{{ '/assets/css/dark.css' | relative_url }}";
document.head.appendChild(darkTheme);
window.addEventListener("DOMContentLoaded", function () {
var list = document.querySelector(".masthead .visible-links");
if (!list) return;
var mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
function handler() {
darkTheme.rel = mediaQuery.matches ? "stylesheet" : "stylesheet alternate";
}
var current = 0;
var modes = ["light", "dark", "auto"];
var modeNames = ["亮色", "暗色", "自动"];
var switcher = document.createElement("a");
switcher.className = "masthead__menu-item";
switcher.innerText = modeNames[current];
switcher.href = "javascript:;";
switcher.onclick = function () {
themeApply(current + 1);
}
list.appendChild(switcher);
function themeApply(index) {
index = (Number(index) || 0) % modes.length;
if (index === current) return;
if (modes[current] === "auto") mediaQuery.removeEventListener("change", handler);
current = index;
var mode = modes[current];
switcher.innerText = modeNames[current];
localStorage.setItem("theme", current);
if (mode === "light") darkTheme.rel = "stylesheet alternate";
else if (mode === "dark") darkTheme.rel = "stylesheet";
else {
mediaQuery.addEventListener("change", handler);
handler();
}
}
themeApply(localStorage.getItem("theme"));
window.addEventListener("storage", function (event) {
event.key === "theme" && themeApply(event.newValue);
});
});
---
layout: null
---
window.addEventListener("DOMContentLoaded", function () {
var skinLink = document.getElementById("skin");
var darkModeQuery = window.matchMedia("(prefers-color-scheme: dark)");
function applyDarkSkin() {
skinLink.href = "{{ '/assets/css/skins/' | relative_url }}" + settings.get("appearance_skin_dark", "dark") + ".css";
}
function applyLightSkin() {
skinLink.href = "{{ '/assets/css/skins/' | relative_url }}" + settings.get("appearance_skin_light", "default") + ".css";
}
function autoSchemeHandler() {
if (darkModeQuery.matches) {
applyDarkSkin();
} else {
applyLightSkin();
}
}
var activeModeIndex = 0;
var modeKeys = ["light", "dark", "auto"];
var modeLabels = ["亮色", "暗色", "自动"];
var menuList = document.querySelector(".masthead .visible-links");
var modeSwitcher = null;
if (menuList) {
modeSwitcher = document.createElement("a");
modeSwitcher.className = "masthead__menu-item";
modeSwitcher.textContent = modeLabels[activeModeIndex];
modeSwitcher.href = "javascript:;";
modeSwitcher.onclick = function () {
var nextIndex = (activeModeIndex + 1) % modeKeys.length;
settings.set("appearance_color", modeKeys[nextIndex]);
}
menuList.appendChild(modeSwitcher);
}
function applyTheme(mode) {
var newIndex = modeKeys.indexOf(mode);
if (newIndex < 0) newIndex = 0;
if (modeKeys[activeModeIndex] === "auto") {
darkModeQuery.removeEventListener("change", autoSchemeHandler);
}
activeModeIndex = newIndex;
var resolvedMode = modeKeys[activeModeIndex];
if (modeSwitcher) {
modeSwitcher.textContent = modeLabels[activeModeIndex];
}
if (resolvedMode === "light") {
applyLightSkin();
}
else if (resolvedMode === "dark") {
applyDarkSkin();
}
else {
darkModeQuery.addEventListener("change", autoSchemeHandler);
autoSchemeHandler();
}
}
settings.onChange("appearance_color", applyTheme);
settings.onChange("appearance_skin_dark", function () {
settings.refresh("appearance_color");
});
settings.onChange("appearance_skin_light", function () {
settings.refresh("appearance_color");
});
});