394613f516
- 设置入口 group 改为官方 interface(外观)分组 - 删除侧边栏 ThemeToggle 注入器及组件,设置页成为唯一入口 - verify-toggle.py 改为直接驱动主题状态并校验翻转 - 同步 README 与脚本文档,版本升级 1.0.6
81 lines
5.8 KiB
Markdown
81 lines
5.8 KiB
Markdown
# 问题交接单:深色模式入口去重 + 菜单分组调整(2026-08-08)
|
||
|
||
> 审查窗口产出,**交付开发窗口执行**;审查窗口不修改代码。
|
||
> 用户需求(已确认):① 深色模式设置入口从"偏好设置"移到 Halo 官方"外观"分组;② 移除侧边栏底部注入的切换按钮(与菜单入口重复,用户判定多余)。
|
||
> 前置说明:真实环境取证于 `blog.liuhangyv.top/console`(已登录),见"问题描述"。
|
||
|
||
## 一、问题描述
|
||
|
||
### 问题 1:深色模式存在两个入口,功能重复
|
||
|
||
当前 Halo 后台对"深色模式"有两个入口:
|
||
|
||
- **入口 A(侧边栏底部切换按钮)**:插件注入的 `ThemeToggle` 按钮(显示"浅色模式 / 深色模式",点击一键切换)。
|
||
- **入口 B(侧边栏菜单项)**:「偏好设置 → 深色模式」设置页(浅色 / 深色 / 跟随系统三选一)。
|
||
|
||
用户观察到侧边栏底部有两个"切换"类入口,底部注入的按钮闲置不用,判定没有必要,要求移除。
|
||
|
||
**真实环境取证结果**(消除歧义):
|
||
- 侧边栏底部**只有 1 个**主题切换按钮:插件注入的 `plugin-dark-mode-toggle`(位于 `sidebar__profile` 上方),工作正常。
|
||
- 用户信息区(`user-profile__actions`)另外两个图标按钮是 Halo 官方「个人资料(跳 /uc)」和「退出登录」——已核对官方源码 `ui/src/layouts/UserProfileBanner.vue`,**不是**主题切换。
|
||
- 因此用户所说的"两个切换按钮" = 入口 A(底部注入按钮)+ 入口 B(菜单项),二者功能重复,保留其一即可。
|
||
|
||
### 问题 2:设置页入口挂在自建分组"偏好设置"下
|
||
|
||
- 现状:菜单 `group` 为字符串 `'偏好设置'`。这不是 Halo 标准分组 key,Halo 找不到对应 i18n 翻译,直接将该字符串作为分组标题显示,于是在侧边栏多出"偏好设置"分组(其中只有"深色模式"一项)。
|
||
- 期望:放入 Halo 官方**「外观」**分组(主题 / 菜单 / 插件所在)。
|
||
- 背景:Halo 2.25 官方分组 key(`halo-dev/halo` `ui/console-src/router/constant.ts`):`dashboard`、`content`、`interface`、`system`、`tool`。其中 **`interface` 即"外观"**(实测该分组内已有主题 / 菜单 / 插件)。
|
||
|
||
## 二、问题在代码中的具体体现
|
||
|
||
| # | 文件 | 位置 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| 1 | `ui/src/index.ts` | L5 | `import { injectThemeToggle } from './injector'` |
|
||
| 2 | `ui/src/index.ts` | L7-L8 | 模块加载时执行 `injectThemeToggle()` → 注入入口 A |
|
||
| 3 | `ui/src/index.ts` | L26 | `group: '偏好设置'` → 自建字面量分组(入口 B 位置错误) |
|
||
| 4 | `ui/src/injector.ts` | 全文 | 入口 A 的注入器:`CONTAINER_CLASS = 'plugin-dark-mode-toggle'`(L4)、`TARGET_SELECTOR = '.sidebar__profile'`(L5)、`injectThemeToggle()` 用 `MutationObserver` 等待侧边栏渲染(L13-L31)、`tryMount()` 将容器插入 profile 上方并 `render(ThemeToggle)`(L33-L48) |
|
||
| 5 | `ui/src/components/ThemeToggle.vue` | 全文 | 入口 A 的按钮本体(class `theme-toggle`,文案"浅色模式 / 深色模式") |
|
||
|
||
**连带影响(改动入口 A 时必须同步处理):**
|
||
|
||
| # | 文件 | 位置 | 影响 |
|
||
| --- | --- | --- | --- |
|
||
| 6 | `scripts/verify-toggle.py` | L40-L43 | 依赖 `.theme-toggle` 定位点击验证,移除按钮后脚本失效 |
|
||
| 7 | `README.md` | L11 / L19 / L23 / L111 / L116 / L130 / L138 | 多处描述"侧边栏一键切换 / UserProfileBanner / 注入器" |
|
||
| 8 | `CLAUDE.md` / `AGENTS.md` | L54 / L59 / L86-L88 | 架构树与"ThemeToggle 侧边栏注入"章节(gitignored,本地维护) |
|
||
|
||
**不涉及**:`useDarkMode.ts`、`darkreader-engine.ts`、`SettingsView.vue` 均无需改动(入口 B 及其状态管理完全独立)。
|
||
|
||
## 三、修改建议(供开发窗口执行)
|
||
|
||
### 推荐方案:移分组 + 移除侧边栏注入按钮
|
||
|
||
1. **`ui/src/index.ts`**
|
||
- L26:`group: '偏好设置'` → `group: 'interface'`(进入"外观"分组)
|
||
- L5:删除 `import { injectThemeToggle } from './injector'`
|
||
- L7-L8:删除调用与注释
|
||
2. **删除文件(需用户书面确认,AGENTS.md 约定)**
|
||
- `ui/src/injector.ts`
|
||
- `ui/src/components/ThemeToggle.vue`
|
||
3. **`scripts/verify-toggle.py`**
|
||
- 移除 L40-L43 对 `.theme-toggle` 的点击依赖
|
||
- 改为直接驱动状态 + 断言,例如:`localStorage.setItem('halo-dark-mode-theme', 'dark'/'light')` 后断言 `data-halo-theme`、`data-darkreader-mode`、`color-scheme` 翻转;保留现有三向 PASS 判定逻辑
|
||
4. **文档同步**
|
||
- `README.md`:功能特性去掉"侧边栏一键切换"、使用说明改为"进入「外观 → 深色模式」"、项目结构删除 injector/ThemeToggle 两行、验证脚本描述更新
|
||
- `CLAUDE.md` / `AGENTS.md`:删除"ThemeToggle 侧边栏注入"章节,更新架构树
|
||
5. **构建与回归**
|
||
- `cd ui && pnpm build`、`pnpm type-check`、`pnpm prettier`、`pnpm lint`、`pnpm test:unit`
|
||
- 根目录 `gradlew build`
|
||
- 部署后跑 `scripts/verify-toggle.py`(改版后)
|
||
|
||
### 备选方案:仅移分组(保留侧边栏按钮)
|
||
|
||
- 只改 `ui/src/index.ts` L26 为 `'interface'`;验证脚本与文档均不用动。
|
||
- 适合希望保留"一键切换"快捷方式的场景;但无法满足用户"移除多余按钮"的诉求。
|
||
|
||
## 四、注意事项
|
||
|
||
- **删除文件必须先获得用户书面同意**(项目 AGENTS.md 明确"未经书面同意不得删除任何文件");用户本意是"没必要保留入口 A",可据此向用户确认后执行。
|
||
- 移除入口 A 后,设置页(`SettingsView.vue`)成为唯一入口,属预期结果,保留即可。
|
||
- `useDarkMode` 的 localStorage 持久化、storage 跨标签同步、Dark Reader 引擎均与入口 A 无关,不受影响。
|
||
- 版本号建议随本次改动递增(如 1.0.6),并同步 `plugin.yaml`(如需)与 `@since`。 |