feat(theme): 导航页恢复自动深浅色(跟随系统),保留隐藏原生设置入口

用户反馈:现在没有自动深/浅色。实测原因有两层:
1. Dashy 原生的日/夜切换按钮在设置面板里,而该面板按要求被隐藏;
2. navi.css 没有任何 prefers-color-scheme 分支,且多处写死亮色。

本提交按"我们自己接管"实现(不去赌 Dashy 压缩后的主题存储键):
- navi.js:默认跟 prefers-color-scheme;手动切换过以 localStorage.navi-theme 为准;
  系统偏好变化实时跟随;给 <html> 设 data-theme 与 .navi-dark,并设 color-scheme。
  Dashy 挂载后可能覆写 data-theme,用短暂定时对齐 + 属性观察器收口
  (仅在"与期望不一致"时回写,避免自激循环)。
- navi.css:深色下覆盖页面底色与文字,以及我们自己注入的悬浮控件
  (搜索条/收边控件/页脚/工作空间工具条与弹窗/迷你视图标签条)。
  选择器带 body 以压过主题注入的 customCss。

需要人工目视确认观感(深色下的玻璃层次只能靠眼睛调)。
This commit is contained in:
HomeDash Bot
2026-09-11 23:18:54 +08:00
parent c597fa1991
commit a8ce6ad759
2 changed files with 92 additions and 0 deletions

View File

@ -1349,3 +1349,48 @@ html[data-theme] .navi-footer a {
transform: none !important;
}
}
/* ── 深色模式 ──
触发条件:<html data-theme="dark">(由 navi.js 按系统偏好设置)。
这里只覆盖两类东西:① 页面底色/文字;② 我们自己注入的悬浮控件
(原生 Dashy 卡片的观感由主题提供,不在这里重复定义)。
选择器都带 body 以压过主题注入的 customCss(同优先级时后者更具体)。 */
html[data-theme="dark"] body {
background-color: #0b1120 !important;
color: #e8eefc !important;
}
html[data-theme="dark"] body .navi-search-bar,
html[data-theme="dark"] body .navi-dock,
html[data-theme="dark"] body .navi-footer-host,
html[data-theme="dark"] body .navi-ws-toolbar,
html[data-theme="dark"] body .navi-ws-modal {
background: rgba(17, 25, 40, 0.78) !important;
border-color: rgba(148, 163, 184, 0.22) !important;
color: #e8eefc !important;
box-shadow: 0 8px 28px rgba(0, 0, 0, 0.45) !important;
}
html[data-theme="dark"] body .navi-search-bar input,
html[data-theme="dark"] body .navi-search-bar .navi-search-input {
background: rgba(15, 23, 42, 0.6) !important;
color: #e8eefc !important;
border-color: rgba(148, 163, 184, 0.25) !important;
}
html[data-theme="dark"] body .navi-search-bar input::placeholder { color: #94a3b8 !important; }
html[data-theme="dark"] body .navi-footer,
html[data-theme="dark"] body .navi-footer a,
html[data-theme="dark"] body .navi-footer .navi-footer-sep { color: #94a3b8 !important; }
html[data-theme="dark"] body .navi-footer a:hover { color: #60a5fa !important; }
html[data-theme="dark"] body .navi-dock button,
html[data-theme="dark"] body .navi-dock a {
background: rgba(30, 41, 59, 0.72) !important;
color: #cbd5e1 !important;
border-color: rgba(148, 163, 184, 0.22) !important;
}
html[data-theme="dark"] body .navi-dock button:hover,
html[data-theme="dark"] body .navi-dock a:hover { color: #93bbfd !important; }
html[data-theme="dark"] body .minimal-section-inner,
html[data-theme="dark"] body div.item-wrapper {
background: rgba(17, 25, 40, 0.6) !important;
border-color: rgba(148, 163, 184, 0.18) !important;
}
html[data-theme="dark"] body .navi-mini-tabs { background: rgba(11, 17, 32, 0.85) !important; }

View File

@ -640,3 +640,50 @@
}
new MutationObserver(run).observe(document.documentElement, { childList: true, subtree: true });
})();
/* ── 自动深浅色(跟随系统)──
Dashy 原生的日/夜开关在设置面板里,而该面板被隐藏(用户要求隐藏原生设置),
所以这里由我们自己跟随系统偏好:
· 默认按 prefers-color-scheme 决定
· 手动切换过(localStorage.navi-theme)则以手动为准
· 系统偏好变化时实时跟随
Dashy 挂载后可能重设 data-theme,故用短暂的定时对齐 + 属性观察收口。 */
(function () {
var KEY = 'navi-theme';
var mq = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)');
if (!mq) return;
function wantDark() {
var saved = null;
try { saved = localStorage.getItem(KEY); } catch (e) { /* 隐私模式 */ }
return saved === 'dark' ? true : saved === 'light' ? false : mq.matches;
}
function apply() {
var dark = wantDark();
var root = document.documentElement;
var name = dark ? 'dark' : 'light';
if (root.getAttribute('data-theme') !== name) root.setAttribute('data-theme', name);
root.classList.toggle('navi-dark', dark);
root.style.colorScheme = name;
}
apply();
if (mq.addEventListener) mq.addEventListener('change', apply);
else if (mq.addListener) mq.addListener(apply);
// Dashy 挂载后可能覆写 data-theme:前 15 秒内对齐,之后交给下面的观察器
var tries = 0;
var timer = setInterval(function () {
apply();
if (++tries >= 30) clearInterval(timer);
}, 500);
// 只在"与期望不一致"时回写,避免与自身写入形成循环
try {
new MutationObserver(function () {
var name = wantDark() ? 'dark' : 'light';
if (document.documentElement.getAttribute('data-theme') !== name) apply();
}).observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme'] });
} catch (e) { /* 老浏览器忽略 */ }
})();