diff --git a/dash/docs/theme-switching-plan.zh.md b/dash/docs/theme-switching-plan.zh.md index e2aad1e..a60c5cc 100644 --- a/dash/docs/theme-switching-plan.zh.md +++ b/dash/docs/theme-switching-plan.zh.md @@ -1,213 +1,262 @@ -# Kindle Dashboard 多主题切换方案 +# Kindle Dashboard 多主题方案 ## 1. 背景 -当前仓库已经具备一条稳定的单主题链路: +当前链路已经稳定分成两部分: -- `calendar/` 负责渲染仪表盘网页,并导出 `kindlebg.png` -- `dash/` 运行在 Kindle 上,按固定 URL 拉取背景图 -- Kindle 本机每分钟只重画时钟区域,不重新联网渲染整页 +- `calendar/` 负责渲染网页和导出背景图 +- `dash/` 运行在 Kindle 上,负责拉取背景图并在本地重画时钟 -当前关键约束如下: +这里先明确一个约束,后续方案都基于它展开: -- Kindle 端默认只认识一个背景地址:`BACKGROUND_URL` -- 背景图文件名固定为 `kindlebg.png` -- 本机时钟素材与时钟区域参数由 Kindle 本地管理 -- KUAL 菜单当前只有启动和调试入口,没有切换主题入口 +- Kindle 端仍然保持“拉背景图片 + 绘制时钟”的职责 +- 不把整页日历渲染放回 Kindle +- 主题的名称、路径、时钟占位信息都由 `calendar/` 提供 -这意味着“多主题”不能只靠改前端样式,还需要把主题标识、产物路径和 Kindle 侧的选择逻辑一起设计出来。 +这次多主题方案要同时满足两类需求: + +1. 访问 `calendar` 网站时,可以在页面上切换主题预览效果 +2. 后续 Kindle 端如果需要切换主题,也只依赖 `calendar` 提供的主题配置,不自己猜路径或布局 ## 2. 目标 -本方案要解决的问题是: +本方案的目标是: -1. 访问 `calendar` 网站时,可以通过菜单预览不同主题样式 -2. 现有日历背景生成流程保持兼容,不因预览主题而被破坏 -3. 后续如果需要,`calendar/` 仍能稳定产出多个主题的背景图 -4. Kindle 能在不改代码、不重新部署整套程序的前提下切换当前主题 -5. 主题切换后,下一次背景刷新即可生效 -SH: 主题切换后,即刻拉取一次 -6. 后续如果主题不仅改背景,还改表盘素材与时钟区域,也能平滑扩展 +1. 访问网站时,可以通过顶部可选菜单切换主题样式 +2. 网站预览效果应尽量与 Kindle 最终显示效果一致 +3. 当前背景生成流程继续可用,不因主题预览被破坏 +4. `calendar/` 提供统一的主题清单 JSON,作为主题的单一真相源 +5. Kindle 只需要读取固定位置的主题清单和主题配置 JSON +6. Kindle 切换主题后,应立即拉取该主题背景和主题级配置并刷新 +7. 时钟的位置、尺寸和绘制参数由 `calendar` 的主题配置决定,Kindle 不自行决定 非目标: -- 不在 Kindle 上重新渲染整张日历页 -- 不引入 Kindle 端复杂主题模板引擎 -SH: kindle端还是保持,拉背景图片+绘制时钟 -- 不要求首次版本就支持任意数量主题的自动发现 -SH:主题清单(名称和路径等信息),可以放在calendar项目下,用json文件,比如themes.json,kindle可以一天同步一次该主题,或者主动拉取。 +- 不在 Kindle 上重新渲染整张页面 +- 不让 Kindle 维护主题路径规则 +- 不要求第一阶段就把现有导出脚本改成强制批量导出 +- 不要求第一阶段就做“本地表盘素材包”体系 ## 3. 设计原则 -### 3.1 渲染留在 `calendar/` +### 3.1 `calendar/` 是主题真相源 -推荐继续保持现有职责边界: +主题系统的单一真相源放在 `calendar/` 侧。 -- `calendar/` 负责主题样式、布局、导出 -- Kindle 只负责选择当前主题并拉取对应产物 +建议由 `calendar/` 产出: -原因: +- 一个主题清单文件,例如 `themes.json` +- 每个主题自己的配置文件,例如 `default.json`、`paper.json` +- 每个主题自己的背景图 -- Kindle 算力和调试体验都不适合承载整页主题渲染 -- 当前链路已经验证“远端产图 + 本机分钟级叠时钟”可行 -- 主题扩展主要发生在样式层,天然更适合留在前端工程里 +其中 `themes.json` 至少描述: -SH: 增加主题配置json +- 有哪些主题 +- 每个主题叫什么名字 +- 每个主题的配置 JSON 在哪里 +- 默认主题是谁 -### 3.2 Kindle 只保存“当前主题 ID” +这样做的好处是: -Kindle 端不保存复杂主题配置,只保存一个很小的状态: +- 主题路径由 `calendar` 管理,不在 Kindle 端写死 +- 新增主题时,Kindle 无需改代码里的路径规则 +- 网站预览和 Kindle 切换都依赖同一套主题元数据 -- 当前主题名,例如 `paper` +这里再明确一下边界。 -围绕这个主题名决定: +远端主题配置只有两类: -- 去哪个 URL 拉取背景图 -- 使用哪套本地表盘素材 -- 使用哪份时钟区域配置 +- `themes.json` +- 每个主题自己的 JSON,例如 `themes/default.json` -SH: kindle侧最简化,甚至只需要在固定位置取json来看,calendar支持哪些主题,主题图在哪里取? -时钟大小和和位置等,由calendar维护。kindle所需的信息,可以在主题对应的json中描述,这样kindle不用决定时钟应该画在那里,按json配置即可。 +除此之外: -### 3.3 先做“背景主题切换”,再做“完整主题切换” +- 背景图属于资源文件,不属于主题配置 +- Kindle 本地缓存属于运行时状态,不属于主题配置 -建议分两阶段: +### 3.2 网站预览与导出解耦 -- 阶段 1:只切换背景主题,保持本地表盘素材不变 -- 阶段 2:背景、表盘素材、时钟区域一起切换 - -这样可以先验证交互链路和配置模型,再扩展到完整主题包。 - -### 3.4 预览与导出解耦 - -主题预览只是 `calendar` 网站访问时的交互能力,不应反向改变现有导出主流程。 +主题预览只是网站访问时的交互能力,不应破坏当前导出主流程。 建议明确两条链路: -- 预览链路:用户访问网站,通过菜单切换 `theme` -SH:这个没问题,只要看效果就行了。且效果和kindle上显示一致就行了。 -- 导出链路:脚本继续按当前默认行为生成 `calendar/dist/kindlebg.png` -SH:主题的路径管理由calendar决定,路径不写死,不通主题不通路径 +- 预览链路:用户访问 `/?mode=full&theme=`,通过页面菜单切换主题 +- 导出链路:现有脚本继续生成默认背景图,保持兼容 -只有在后续正式接入 Kindle 多主题切换时,再额外增加“按主题导出”的产物目录。 +也就是说: -## 4. 方案总览 +- 预览能力先落地 +- 当前 `kindlebg.png` 导出链路先不强制变化 +- 多主题导出作为后续增量能力接入 -### 4.1 推荐架构 +### 3.3 Kindle 侧最简化 -推荐采用“主题目录 + 当前主题状态文件”的方式。 +Kindle 侧只保留最小能力: -远端发布结构: +- 拉取背景图 +- 读取主题 JSON +- 按 JSON 提供的时钟参数绘制时钟 + +Kindle 不负责: + +- 推导主题路径 +- 决定时钟区域坐标 +- 维护主题布局规则 + +推荐让 Kindle 只认识一个固定入口,例如: ```text -https://shell.biboer.cn:20001/themes/paper/kindlebg.png -https://shell.biboer.cn:20001/themes/paper/dashboard-manifest.json -https://shell.biboer.cn:20001/themes/classic/kindlebg.png -https://shell.biboer.cn:20001/themes/classic/dashboard-manifest.json +https://shell.biboer.cn:20001/themes.json ``` -Kindle 本地结构: +然后从这个 JSON 中知道: + +- 当前有哪些主题 +- 每个主题的配置 JSON 在哪里 +- 切换到该主题时该去拉哪个背景图 + +### 3.4 当前时钟实现已经足够轻量 + +当前 Kindle 侧时钟是本地几何绘制,不依赖外部表盘或指针素材文件。 + +这意味着第一阶段主题切换只需要关注: + +- 背景图 URL +- 时钟区域位置和尺寸 +- 本地绘制时钟所需的参数 + +不需要先引入复杂的“主题素材包”机制。 + +## 4. 数据约定 + +### 4.1 主题清单 `themes.json` + +建议由 `calendar/` 在固定位置提供主题清单,例如: + +```json +{ + "updatedAt": "2026-03-16T10:00:00+08:00", + "defaultThemeId": "default", + "themes": [ + { + "id": "default", + "label": "Default", + "configUrl": "https://shell.biboer.cn:20001/themes/default.json", + "previewQuery": "?mode=full&theme=default" + }, + { + "id": "paper", + "label": "Paper", + "configUrl": "https://shell.biboer.cn:20001/themes/paper.json", + "previewQuery": "?mode=full&theme=paper" + }, + { + "id": "classic", + "label": "Classic", + "configUrl": "https://shell.biboer.cn:20001/themes/classic.json", + "previewQuery": "?mode=full&theme=classic" + } + ] +} +``` + +第一阶段建议先保留当前主题并命名为 `default`,然后新增: + +- `paper` +- `classic` + +### 4.2 主题配置 `.json` + +每个主题再提供一份主题级配置,例如: + +```json +{ + "id": "default", + "label": "Default", + "background": { + "url": "https://shell.biboer.cn:20001/themes/default/kindlebg.png", + "refreshIntervalMinutes": 120 + }, + "clock": { + "x": 262, + "y": 55, + "width": 220, + "height": 220, + "faceRadiusRatio": 0.47, + "faceStroke": 3, + "tickOuterInset": 6, + "majorTickLength": 14, + "minorTickLength": 7, + "majorTickThickness": 4, + "minorTickThickness": 2, + "hourLengthRatio": 0.48, + "minuteLengthRatio": 0.72, + "hourThickness": 9, + "minuteThickness": 5, + "centerRadius": 7 + } +} +``` + +说明: + +- 背景图真实路径由主题配置提供,不在 Kindle 端拼接猜测 +- 时钟坐标和大小来自 `calendar` 中该主题的时钟占位,不允许 Kindle 任意改 +- 后续如果某个主题需要不同的时钟绘制参数,也由该 JSON 一起提供 + +### 4.3 Kindle 本地状态 + +Kindle 本地只需要保存少量状态: ```text /mnt/us/dashboard/local/theme.env -/mnt/us/dashboard/local/themes/paper/ -/mnt/us/dashboard/local/themes/classic/ +/mnt/us/dashboard/local/state/themes.json +/mnt/us/dashboard/local/state/current-theme.json +/mnt/us/dashboard/local/state/background-updated-at ``` 其中: - `theme.env` 只记录当前主题 ID -- 每个主题目录可以逐步承载本地专属素材 +- `themes.json` 是最近一次同步到本地的主题清单缓存 +- `current-theme.json` 是当前主题配置缓存 -### 4.2 当前主题状态 +这几项是 Kindle 本地运行状态,不属于远端主题配置。 -建议新增本地状态文件: +## 5. `calendar/` 侧方案 -```sh -export THEME_ID=${THEME_ID:-paper} -``` +### 5.1 网站访问时增加主题预览菜单 -优先级建议如下: - -1. `/mnt/us/dashboard/local/theme.env` -2. `/mnt/us/dashboard/local/env.sh` 中的默认值 -3. 代码里的兜底默认值 - -这样做的好处是: - -- 切换主题不必改主配置文件 -- 主题状态和设备级参数可以分开管理 -- 后续可以由 KUAL 菜单脚本单独改写 `theme.env` - -## 5. `calendar/` 侧改造建议 - -### 5.1 新增 `theme` URL 参数 - -当前已有 `mode` 参数: - -- `/?mode=full` -- `/?mode=background` -- `/?mode=clock-face` - -建议扩展为: - -- `/?mode=full&theme=paper` -- `/?mode=background&theme=paper` -- `/?mode=background&theme=classic` - -约定: - -- `mode` 决定页面用途 -- `theme` 决定视觉主题 - -### 5.2 网站访问时提供主题预览菜单 - -主题预览菜单只服务于网站访问场景,不直接参与背景导出。 +主题预览菜单只出现在网站访问场景,不出现在背景截图结果里。 建议行为: -1. 用户访问 `/?mode=full` 时,可以在页面菜单中切换主题 -2. 菜单切换只更新当前页面的 `theme` 参数 -3. 可以把当前主题同步到 URL,便于分享和复现 -4. 可以选择是否额外写入 `localStorage`,用于下次访问时记住上次预览主题 +1. 用户访问 `/?mode=full` 时,在页面顶部显示一个可选主题菜单 +2. 切换菜单时更新当前页面的 `theme` 参数 +3. 菜单位置放在顶部任意不影响截图的位置即可 +4. 在 `mode=background` 下不显示该菜单,避免影响截图导出 -菜单本身建议只出现在预览页面,不出现在背景导出页面里。 +建议 URL 形态如下: -也就是说: +- `/?mode=full&theme=default` +- `/?mode=full&theme=paper` +- `/?mode=full&theme=classic` -- `/?mode=full&theme=paper` 可以显示主题切换菜单 -- `/?mode=background&theme=paper` 只负责导出背景,不显示菜单 +### 5.2 预览效果与 Kindle 效果对齐 -### 5.3 主题定义集中管理 +主题预览不能只是“网页版好看”,还需要尽量接近 Kindle 最终效果。 -建议在 `calendar/src/` 下引入统一主题描述,例如: +建议做到: -```ts -type ThemeId = 'paper' | 'classic' | 'minimal'; +- 预览和导出使用同一套主题配置 +- 背景导出与预览使用同一套时钟占位信息 +- Kindle 侧按主题 JSON 中的时钟参数绘制,避免预览和实机错位 -type DashboardTheme = { - id: ThemeId; - label: string; - clockRegion: { - x: number; - y: number; - width: number; - height: number; - }; - managedOnKindle: boolean; -}; -``` +这样评审主题时,看到的页面效果和 Kindle 最终效果才是一致的。 -主题配置至少要能描述: +### 5.3 现有导出流程保持兼容 -- 主题 ID -- 主题显示名 -- 时钟区域位置与尺寸 -- 是否依赖 Kindle 本地表盘素材 - -### 5.4 保持现有导出流程兼容 - -当前导出主流程建议保持不变: +当前默认导出链路继续保留: ```text calendar/dist/kindlebg.png @@ -215,300 +264,218 @@ calendar/dist/dashboard-manifest.json calendar/dist/clock-region.json ``` -默认规则: +兼容规则建议如下: -- 如果导出脚本未显式传入 `theme`,就使用默认主题,例如 `paper` -- 继续保留现有 `kindlebg.png` 单产物出口 -- 现有部署和 Kindle 拉图流程无需立刻修改 +- 如果导出脚本没有显式传入 `theme`,默认导出 `default` +- 现有 `export:background` 的行为保持不变 +- 先不强制要求所有主题都参与默认导出 这样可以保证: -- 先落地网站主题预览能力 -- 不打断当前背景导出与发布链路 -- 后续再增量接入主题化产物 +- 网站预览菜单先落地 +- 当前生产链路不被打断 +- Kindle 当前单主题使用方式继续可用 -### 5.5 多主题导出作为附加能力 +### 5.4 多主题导出作为附加能力 -SH:主题清单由calendar供给,kindle只要依据themes.json获取现有什么主题。kindle切换主题时拉一次该主题对应的背景和主题级json。 - -当需要支持 Kindle 端切换主题时,再额外增加按主题导出的能力,例如: +当需要支持 Kindle 端多主题切换时,再增加多主题导出,例如: ```text +calendar/dist/themes.json +calendar/dist/themes/default.json +calendar/dist/themes/default/kindlebg.png +calendar/dist/themes/paper.json calendar/dist/themes/paper/kindlebg.png -calendar/dist/themes/paper/dashboard-manifest.json -calendar/dist/themes/paper/clock-region.json - +calendar/dist/themes/classic.json calendar/dist/themes/classic/kindlebg.png -calendar/dist/themes/classic/dashboard-manifest.json -calendar/dist/themes/classic/clock-region.json ``` -这里的重点是“新增”,不是“替换”: +这里的关键点是: - 原有 `calendar/dist/kindlebg.png` 继续保留 -- 主题目录产物只用于多主题发布和 Kindle 切换 -- 现有单主题导出脚本不需要被强制改成批量导出 +- 多主题目录和 `themes.json` 是新增能力,不是替换能力 +- 主题路径管理由 `calendar` 决定,不在 Kindle 侧固化为固定模式 -建议后续新增独立命令,例如: +## 6. Kindle 侧方案 -- `export:background` 继续生成默认背景 -- `export:themes` 额外生成多个主题目录 +### 6.1 主题发现方式 -### 5.6 `dashboard-manifest.json` 增加主题字段 - -建议每个主题目录下的 manifest 包含: - -```json -{ - "theme": { - "id": "paper", - "label": "Paper" - }, - "background": { - "path": "kindlebg.png", - "url": "https://shell.biboer.cn:20001/themes/paper/kindlebg.png", - "refreshIntervalMinutes": 120 - }, - "clockRegion": { - "x": 262, - "y": 55, - "width": 220, - "height": 220 - }, - "clockFace": { - "path": "assets/clock-face.png", - "managedOnKindle": true - } -} -``` - -核心变化只有两点: - -- 增加 `theme.id` -- 背景 URL 改为带主题目录 - -## 6. Kindle 侧改造建议 - -### 6.1 拉取路径由主题拼装 - -不建议继续把 `BACKGROUND_URL` 写死为单一地址。 - -建议改成两段式配置: - -```sh -export BACKGROUND_BASE_URL=${BACKGROUND_BASE_URL:-"https://shell.biboer.cn:20001/themes"} -export THEME_ID=${THEME_ID:-paper} -``` - -实际拉取地址在运行时拼成: +Kindle 只需要知道一个固定地址: ```text -$BACKGROUND_BASE_URL/$THEME_ID/kindlebg.png +themes.json 的 URL ``` -这样后续新增主题时,不需要再改 Kindle 端脚本逻辑。 +推荐两种同步方式并存: -### 6.2 增加切换脚本 +- 被动同步:Kindle 每天拉取一次 `themes.json` +- 主动同步:用户进入主题切换流程时,先即时拉取最新 `themes.json` -建议新增脚本: +这样能兼顾: -```text -/mnt/us/dashboard/switch-theme.sh -``` +- 平时低频更新 +- 切换主题时拿到最新主题清单 -行为建议: +### 6.2 主题切换流程 -1. 校验主题 ID 是否在允许列表内 -2. 写入 `/mnt/us/dashboard/local/theme.env` -3. 删除或重置背景更新时间戳 -4. 可选:立即重启 `dash.sh`,或等待下一次刷新周期生效 +主题切换时建议执行以下流程: -其中第 3 步很重要,因为如果不清空背景更新时间,当前缓存可能会延迟两个小时才被新主题替换。 +1. 拉取最新 `themes.json` +2. 根据用户选择的主题 ID 找到对应 `configUrl` +3. 拉取该主题对应的 `.json` +4. 将 `THEME_ID` 写入本地 `theme.env` +5. 将主题 JSON 缓存在本地 +6. 立即拉取该主题背景图 +7. 立即执行一次全屏刷新 +8. 之后继续按当前分钟级时钟刷新逻辑运行 -### 6.3 KUAL 菜单作为切换入口 +这里有一个关键要求: -推荐在 KUAL 菜单里增加主题项,例如: +- 主题切换后,不等待下一个两小时周期 +- 而是立即拉取一次新主题背景 -```text -Kindle Dashboard -Theme: Paper -Theme: Classic -Theme: Minimal -Dashboard Debug On -Dashboard Debug Off -``` +### 6.3 时钟绘制保持现有模型 -这样用户在 Kindle 上就能直接切换当前主题,不依赖 SSH。 +当前 Kindle 时钟是本地几何绘制,已经满足主题切换第一阶段需求。 -如果后续主题数量增加到 5 个以上,再考虑改成: +因此 Kindle 侧仍然保持: -- 一个“循环切换下一个主题”的脚本 -- 或由脚本生成菜单 JSON +- 拉背景图片 +- 读取主题 JSON +- 用本地 `lua + fbink` 画时钟 -### 6.4 完整主题包的本地目录 +不需要在第一阶段增加: -当主题不只是改背景,而是还改表盘样式时,建议 Kindle 本地按主题存放资源: +- 表盘图片素材同步 +- 指针图片素材同步 +- 复杂的本地主题资源目录 -```text -/mnt/us/dashboard/local/themes/paper/clock-region.env -/mnt/us/dashboard/local/themes/paper/assets/clock-face.png -/mnt/us/dashboard/local/themes/paper/assets/hour-hand/000.png -/mnt/us/dashboard/local/themes/paper/assets/minute-hand/00.png +如果未来某个主题确实需要独立表盘素材,再在第二阶段扩展。 -/mnt/us/dashboard/local/themes/classic/clock-region.env -/mnt/us/dashboard/local/themes/classic/assets/clock-face.png -``` +### 6.4 主题切换入口 -切换主题时同时切换: +入口建议做成“统一主题入口”,而不是在 KUAL 里硬编码每个主题项。 -- 背景拉取路径 -- 本地时钟素材根目录 -- 时钟区域参数 +目标交互是: -## 7. 两种落地级别 +1. 用户点击“Theme” +2. 设备根据 `themes.json` 获取当前可用主题清单 +3. 用户点击具体主题 +4. 立即切换到该主题 -### 7.1 级别 A:只切背景 +实现上可以接受两种方式: -适用场景: +- KUAL 能直接承载该交互,则由脚本在入口内完成 +- 如果 KUAL 不能直接动态展示,则由脚本先读取 `themes.json`,再生成或更新对应菜单 -- 多个主题只改卡片风格、字体、配色、排版 -- 所有主题共用同一套 Kindle 本地表盘素材 +不管具体 UI 形态如何,数据契约都应保持一致: -优点: +- 主题列表来自 `themes.json` +- 切换行为来自所选主题对应的 `.json` -- 改动最小 -- 风险最低 -- 最快落地 +## 7. 分阶段落地 -限制: - -- 不支持不同主题使用不同表盘位置或不同指针样式 - -SH:现在kindle的时钟绘制不依赖表盘和指针素材吧? - -### 7.2 级别 B:完整主题切换 - -适用场景: - -- 不同主题拥有不同表盘造型 -- 时钟区域位置和尺寸可能变化 -- 指针、刻度、中心点等素材也需要按主题变化 - -优点: - -- 主题能力完整 -- 页面视觉更统一 - -成本: - -- Kindle 本地资源管理会更复杂 -- 切换时需要同步处理更多状态 - -## 8. 推荐实施顺序 - -建议分四步推进。 - -### 第一步:引入主题 ID,但只做单主题兼容 +### 第一阶段:网站主题预览 目标: -- 网站访问时支持 `theme` -- 增加主题预览菜单 -- 默认主题仍然只有 `paper` +- 新增 `theme` 参数 +- 增加顶部主题预览菜单 +- 默认主题命名为 `default` +- 新增 `paper` 和 `classic` 结果: -- 用户可以在网站上切换预览主题 -- 现有背景导出行为保持不变 +- 用户可以在网站上预览三套主题 +- 现有截图导出流程保持不变 -### 第二步:产出双主题背景 +### 第二阶段:主题元数据发布 目标: -- 增加可选的按主题导出能力 -- `calendar/` 能同时生成两个主题目录 -- 发布层能稳定提供两组 URL +- `calendar/` 产出 `themes.json` +- 每个主题产出自己的 `.json` +- 每个主题有独立背景图 URL 结果: -- 远端资源准备完成 -- 现有默认导出链路仍可继续使用 +- 主题列表、主题路径、时钟配置都由 `calendar/` 统一提供 +- Kindle 侧可以开始按 JSON 理解主题系统 -### 第三步:Kindle 支持背景主题切换 +### 第三阶段:Kindle 端主题切换 目标: -- 增加 `theme.env` -- 增加 `switch-theme.sh` -- 增加 KUAL 菜单入口 +- Kindle 能拉取 `themes.json` +- Kindle 能按选择主题拉取对应的 `.json` +- 切换后立即拉取新背景并全屏刷新 结果: -- 用户可以在 Kindle 上切换背景主题 +- Kindle 端正式具备多主题切换能力 +- Kindle 侧仍保持最小职责 -### 第四步:扩展到完整主题包 +### 第四阶段:按需扩展主题能力 -目标: +只有在未来确实出现需求时,再考虑: -- 将时钟素材和时钟区域配置也按主题管理 +- 为某些主题提供独立表盘素材 +- 增加主题级本地资源同步 +- 增加更复杂的主题切换交互 -结果: +这一步不是当前必需项。 -- 主题系统从“背景切换”升级为“完整主题切换” +## 8. 风险与约束 -## 9. 风险与约束 +### 8.1 预览和实机效果偏差 -### 9.1 主题切换后的缓存失效 +如果预览和导出用的不是同一套主题配置,最终会出现: -如果只改了主题 ID,但没有重置背景更新时间戳,Kindle 可能继续显示旧主题缓存。 +- 网页看起来正确 +- Kindle 上时钟错位或背景不一致 -因此切换脚本必须显式清理以下状态之一: +因此必须保证: -- `/mnt/us/dashboard/local/state/background-updated-at` -- 或缓存背景文件本身 +- 预览 +- 导出 +- Kindle 时钟绘制 -### 9.2 主题数量增长后的菜单维护 +都依赖同一套主题元数据。 -若主题数较多,手写 KUAL 菜单会越来越笨重。 +### 8.2 主题切换后的缓存问题 -到那时建议: +如果主题切换后没有立即拉取新背景,Kindle 可能继续显示旧缓存。 -- 用一个脚本根据主题清单生成菜单 -- 或保留“下一个主题”这种单按钮切换方式 +因此切换主题时必须同时处理: -### 9.3 远端发布必须保持目录稳定 +- 更新 `THEME_ID` +- 拉取新的 `.json` +- 拉取新的背景图 +- 重置背景更新时间戳或直接覆盖缓存背景 -一旦 Kindle 端按 `/themes//kindlebg.png` 约定拉图,发布层就必须保持目录和文件名稳定,否则会出现主题切换后 404。 +### 8.3 主题清单缓存过旧 -## 10. 推荐结论 +如果 Kindle 长时间只读本地缓存,可能看不到新主题。 + +因此建议: + +- 日常低频同步一次 `themes.json` +- 用户进入主题切换时再主动刷新一次 + +## 9. 推荐结论 推荐采用下面这条路线: -1. 保持“`calendar/` 渲染,Kindle 只拉图和切换主题 ID”的职责边界 -2. 先实现网站访问时的主题预览菜单,并保持现有导出流程不变 -3. 再增量接入“背景主题切换” -4. 等确认交互和运维链路稳定后,再升级到“完整主题包” +1. 先在 `calendar` 网站上增加顶部主题预览菜单 +2. 维持当前默认背景导出链路不变 +3. 由 `calendar` 增量提供 `themes.json` 和主题级 `.json` +4. Kindle 只读取固定位置的 `themes.json` +5. 切换主题时立即拉取该主题配置和背景图,并继续使用现有本地时钟绘制 -这个路线最符合当前仓库的实际状态: +这条路线的优点是: -- 复用现有 `mode` 和导出链路 -- 不会打断当前 `kindlebg.png` 生成与发布流程 -- 对 Kindle 主循环改动小 -- 不会把主题复杂度压到 Kindle 设备上 -- 后续也能自然扩展到本地表盘素材切换 - -## 11. 待确认问题 - -进入实现前,建议先明确这几个评审点: - -1. 网站预览菜单放在哪个区域最合适,是否只在 `mode=full` 显示 -SH:这个没有问题,放在顶部的随意位置,可选即可,不影响截图效果。 -2. 第一阶段是否只做 2 个主题,例如 `paper` 和 `classic` -SH:保持当前主题,命名为default,新增这两个。 -3. 第一阶段主题是否允许改变时钟区域位置 -SH:这个位置由calendar中时钟的占位位置决定,按主题时钟位置,不是随意改变。 -4. KUAL 菜单是否接受“每个主题一个菜单项”的交互形式 -SH:统一主题配置,点进去从themes.json获取主题清单,点具体主题,切换主题 -5. 远端发布目录是否可以稳定提供 `/themes//kindlebg.png` - -如果以上五点都确认,本方案可以直接拆成小步实现。 +- 不打断现有 `kindlebg.png` 生成流程 +- 主题路径和布局都由 `calendar` 统一管理 +- Kindle 侧实现最简化 +- 预览和实机显示可以基于同一套配置对齐 +- 当前时钟实现不依赖表盘和指针素材,第一阶段改造成本低