First Push

This commit is contained in:
喆OvO
2026-08-06 11:11:11 +08:00
commit 0fef309972
551 changed files with 15793 additions and 0 deletions
+64
View File
@@ -0,0 +1,64 @@
/* 主题系统:账户独立主题(dark/light/auto)。
*
* - 后端 GET /api/theme 返回 {mode, effective};auto 已解析为 dark/light
* (按用户经纬度+时区计算日出日落)。
* - 应用方式:html 元素加 .theme-light class(CSS 变量覆盖浅色)。
* - 切换动画:切换瞬间给 html 加 .theme-anim,触发全局 CSS transition
* 平滑渐变,平时无全局 transition(不影响交互反馈)。
* - auto 模式每 5 分钟轮询一次(日落日出边界切换);显示端还会在收到
* SSE theme_changed 时立即刷新。
*/
(function (global) {
'use strict';
var current = 'dark';
var pollTimer = null;
function apply(effective) {
if (!effective) return;
if (effective === current) return;
current = effective;
var root = document.documentElement;
root.classList.add('theme-anim');
root.classList.toggle('theme-light', effective === 'light');
// 过渡结束后移除动画 class,恢复常规交互反馈
setTimeout(function () { root.classList.remove('theme-anim'); }, 600);
}
function fetchTheme(cb) {
var xhr = new XMLHttpRequest();
xhr.open('GET', '/api/theme');
xhr.onload = function () {
if (xhr.status === 200) {
var d = {};
try { d = JSON.parse(xhr.responseText || '{}'); } catch (e) {}
if (d.effective) apply(d.effective);
if (cb) cb(d);
}
};
xhr.onerror = function () { /* 网络失败保持当前主题 */ };
xhr.send();
}
function initTheme() {
fetchTheme();
if (!pollTimer) {
// auto 模式日落/日出切换:每 5 分钟刷新一次
pollTimer = setInterval(fetchTheme, 5 * 60 * 1000);
}
}
global.ThemeBridge = {
apply: apply,
fetch: fetchTheme,
init: initTheme,
getCurrent: function () { return current; }
};
// 页面加载即应用主题
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initTheme);
} else {
initTheme();
}
})(window);