2026-08-08 21:14:44 +08:00

Halo 深色模式

为 Halo 后台管理面板提供深色/浅色模式切换,内置 Dark Reader 通用暗色引擎,支持手动切换、跟随系统与偏好记忆。

功能特性

  • 三种模式:浅色、深色、跟随系统
  • 偏好持久化:自动记忆用户选择(localStorage),刷新不丢失
  • 系统偏好跟随:切换系统外观时自动响应
  • Dark Reader 引擎:自动分析页面 CSS 与 DOM,覆盖 Halo 核心页面和第三方插件页面
  • 官方外观分组:设置入口位于 Halo「外观」分组,与主题、菜单、插件同组
  • 设置页面:在「外观 → 深色模式」中详细选择显示模式
  • 零后端依赖:纯前端实现,不需要额外后端 API

安装

  1. 从 Releases 下载 plugin-dark-mode-<version>.jar
  2. 在 Halo 后台的「插件管理」中上传并安装。
  3. 启用插件后,进入「外观 → 深色模式」设置页面调整主题。

使用

安装并启用后,进入「外观 → 深色模式」设置页面选择显示模式:

配置项 可选值 说明
主题模式 light 始终使用浅色模式
主题模式 dark 始终使用深色模式
主题模式 auto 跟随系统外观自动切换

截图预览

以下截图展示插件在 Halo 后台的实际效果。

插件设置界面

后台深色模式效果 1

后台深色模式效果 2

后台深色模式效果 3

技术原理

  • 插件通过 useDarkMode() 管理 light / dark / auto 三种状态。
  • 深色模式下调用 Dark Reader 的 enable(),浅色模式下调用 disable()
  • Dark Reader 会持续监听页面 DOM 变化,因此第三方插件动态渲染的内容也能自动转换。
  • 插件自身只保留设置页所需的最小 UI 变量,不再维护逐页手工 CSS 覆盖。

说明:Dark Reader 的样式注入是异步的,刷新瞬间仍可能存在极短闪白;插件通过同步设置 color-scheme 缓解,但无法完全消除。

第三方依赖

  • Dark Reader 4.9.129MIT License
  • 构建所需文件位于 third-party/darkreader/,由 ui/package.json 通过本地文件依赖引用。
  • 升级或替换 Dark Reader 构建文件后,请校验 third-party/darkreader/SHA256SUMS Linux / macOS 使用 sha256sum -c SHA256SUMSWindows 使用 Get-FileHash -Algorithm SHA256 对比。

开发环境

  • Halo >=2.25.0
  • Java 21+(项目使用 --release 21 编译)
  • Node.js 18+
  • pnpm
  • DockerhaloServer 开发服务器需要)

从源码构建

仓库使用标准 Gradle 结构,并提交了 Gradle Wrapper。

Linux / macOS

./gradlew clean build

Windows

.\gradlew.bat clean build

构建产物位于 build/libs/plugin-dark-mode-<version>.jar

前端开发

cd ui
pnpm install
pnpm dev

常用检查命令:

pnpm type-check   # TypeScript 类型检查
pnpm lint         # Lintoxlint + eslint
pnpm build        # 生产构建

项目结构

├── build.gradle              # 根构建配置
├── settings.gradle           # 包含 :ui 子项目
├── gradle/wrapper/           # Gradle Wrapper
├── src/
│   └── main/
│       ├── java/run/halo/darkmode/
│       │   └── DarkModePlugin.java    # 插件主类(极简骨架)
│       └── resources/
│           └── plugin.yaml            # 插件清单
│
├── third-party/
│   └── darkreader/           # Dark Reader 构建产物(MIT
│
└── ui/
    ├── package.json          # 前端依赖
    ├── vite.config.ts        # Vite 配置
    └── src/
        ├── index.ts                   # definePlugin 入口
        ├── darkreader-engine.ts       # Dark Reader 通用暗色引擎
        ├── composables/
        │   ├── useDarkMode.ts         # 主题状态管理(模块级单例)
        │   └── useSystemPreference.ts # 系统偏好监听
        ├── views/
        │   └── SettingsView.vue       # 设置页面
        └── styles/
            ├── index.css              # 样式入口
            └── variables.css          # 插件自身 UI 变量

测试

./gradlew test

运行时验证脚本位于 scripts/verify-toggle.py,用于直接驱动主题状态,并检查 data-halo-theme、localStorage、Dark Reader 注入与 color-scheme 的翻转。

更新日志

v1.0.8

  • 设置页改用 Halo 官方 VPageHeader / VCard / VDescription / VTag 组件,与官方页面风格统一
  • 精简插件自身 CSS 变量,仅保留设置页所需变量

v1.0.7

  • 移除设置页方向键切换、roving tabindex 与 ARIA 单选组语义,保留原生按钮点击切换
  • 同步清理 README 中已过时的「设置选项支持键盘操作」描述

v1.0.6

  • 深色模式设置入口移至 Halo 官方「外观」分组
  • 移除侧边栏底部注入的切换按钮,设置页成为唯一入口
  • 更新运行时验证脚本:直接驱动主题状态,不再依赖侧边栏按钮

v1.0.5

  • 同步设置 color-scheme,缓解深色模式刷新闪烁
  • 增加多标签页主题同步与 useDarkMode 单元测试
  • 后端日志改用 Lombok @Slf4j
  • 裁剪 vendored package.json,新增 Dark Reader SHA256SUMS 完整性校验
  • plugin.yaml 改为安装后由用户手动启用

v1.0.4

  • 改为纯 Dark Reader 引擎,移除手工 CSS 覆盖
  • 移除 Monaco 手动主题同步,暗色转换统一交给 Dark Reader
  • 整理 third-party/darkreader 目录,仅保留构建所需文件

v1.0.3

  • 引入 Dark Reader 通用暗色引擎
  • 保留原有手工 CSS 作为兼容层,覆盖核心页面与第三方插件页面
  • 增加 Monaco 日志查看器主题同步

许可证

GPL-3.0 © LHY

S
Description
Halo 2.25 暗色模式插件 — 为 Halo 后台管理面板提供深色/浅色模式切换,支持跟随系统、手动切换和偏好记忆。
Readme GPL-3.0 4.1 MiB
1.0.5 Latest
2026-08-08 18:28:57 +08:00
Languages
Python 36.2%
HTML 30.4%
TypeScript 19.1%
CSS 6.7%
Vue 5.2%
Other 2.4%