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