update at 2026-03-17 10:37:27
This commit is contained in:
@@ -1,4 +1,52 @@
|
||||
# Kindle Dashboard 多主题方案
|
||||
# Kindle Dashboard 多主题与方向方案
|
||||
|
||||
## 0. 当前实现状态(2026-03-16)
|
||||
|
||||
以下能力已经落地,不再只是设计目标:
|
||||
|
||||
- `calendar/` 网站已支持 `theme + orientation` 两维预览
|
||||
- `mode=background` 下不会显示预览菜单,避免污染截图
|
||||
- `calendar/` 已产出:
|
||||
- `dist/themes.json`
|
||||
- `dist/themes/<theme-id>.json`
|
||||
- `dist/themes/<theme-id>/<orientation>/kindlebg.png`
|
||||
- 兼容输出仍保留:
|
||||
- `dist/kindlebg.png`
|
||||
- `dist/clock-region.json`
|
||||
- Kindle 已支持:
|
||||
- 拉取 `themes.json` 和主题级 JSON
|
||||
- 通过 `/mnt/us/dashboard/switch-theme.sh <theme-id> [orientation]` 立即切换
|
||||
- 优先使用本地已同步的主题背景图
|
||||
- 优先使用本地已同步的主题索引和主题 JSON
|
||||
- 本地没有对应背景图时,再回退到远端 `background.url`
|
||||
- 同步脚本 `scripts/sync-layered-clock-to-kindle.sh` 会先批量导出全部主题背景,再把 `/mnt/us/dashboard/themes/` 同步到设备
|
||||
|
||||
### 0.1 横向主题的抓屏评审约定
|
||||
|
||||
`fbgrab` 抓到的是 Kindle 的原始 framebuffer 图,尺寸始终是纵向的 `1072 x 1448`。
|
||||
|
||||
这意味着:
|
||||
|
||||
- `portrait` 主题下,`physical.png` 与 `raw.png` 相同
|
||||
- `landscape` + `logo_right` 主题下,日常评审应优先看 `physical.png`
|
||||
- `raw.png` 只用于排查原始 framebuffer 坐标
|
||||
- `physical.png` 等于把 raw 图按设备实际摆放方向逆时针旋转 90 度后的结果
|
||||
|
||||
仓库里已经补了一个辅助脚本:
|
||||
|
||||
```sh
|
||||
sh scripts/capture-kindle-screen.sh kindle landscape-check
|
||||
```
|
||||
|
||||
它会同时输出两张图:
|
||||
|
||||
- `tmp/landscape-check-raw.png`
|
||||
- `tmp/landscape-check-physical.png`
|
||||
|
||||
其中:
|
||||
|
||||
- `raw.png` 用于排查 framebuffer 原始坐标
|
||||
- `physical.png` 用于按 Kindle 实际摆放方向评审横向主题
|
||||
|
||||
## 1. 背景
|
||||
|
||||
@@ -7,39 +55,48 @@
|
||||
- `calendar/` 负责渲染网页和导出背景图
|
||||
- `dash/` 运行在 Kindle 上,负责拉取背景图并在本地重画时钟
|
||||
|
||||
这里先明确一个约束,后续方案都基于它展开:
|
||||
这次方案先明确两个概念:
|
||||
|
||||
- `theme`:视觉主题,例如 `default`、`paper`、`classic`
|
||||
- `orientation`:显示方向,例如 `portrait`、`landscape`
|
||||
|
||||
其中方向不是主题名的一部分,而是每个主题都必须包含的两套样式:
|
||||
|
||||
- `portrait`
|
||||
- Kindle 竖向摆放
|
||||
- 设备外部面板上的 `kindle` logo 在下方
|
||||
- `landscape`
|
||||
- Kindle 横向摆放
|
||||
- 设备外部面板上的 `kindle` logo 在右侧
|
||||
|
||||
也就是说,后续系统模型应当是:
|
||||
|
||||
- 每个主题都包含纵向和横向两套显示样式
|
||||
- Kindle 端仍然保持“拉背景图片 + 绘制时钟”的职责
|
||||
- 不把整页日历渲染放回 Kindle
|
||||
- 主题的名称、路径、时钟占位信息都由 `calendar/` 提供
|
||||
|
||||
这次多主题方案要同时满足两类需求:
|
||||
|
||||
1. 访问 `calendar` 网站时,可以在页面上切换主题预览效果
|
||||
2. 后续 Kindle 端如果需要切换主题,也只依赖 `calendar` 提供的主题配置,不自己猜路径或布局
|
||||
- 时钟的位置、尺寸和绘制参数都由 `calendar/` 提供
|
||||
|
||||
## 2. 目标
|
||||
|
||||
本方案的目标是:
|
||||
|
||||
1. 访问网站时,可以通过顶部可选菜单切换主题样式
|
||||
1. 访问网站时,可以切换主题和方向进行预览
|
||||
2. 网站预览效果应尽量与 Kindle 最终显示效果一致
|
||||
3. 当前背景生成流程继续可用,不因主题预览被破坏
|
||||
4. `calendar/` 提供统一的主题清单 JSON,作为主题的单一真相源
|
||||
3. 当前背景生成流程继续可用,不因预览能力被破坏
|
||||
4. `calendar/` 提供统一的主题清单 JSON,作为主题与方向配置的单一真相源
|
||||
5. Kindle 只需要读取固定位置的主题清单和主题配置 JSON
|
||||
6. Kindle 切换主题后,应立即拉取该主题背景和主题级配置并刷新
|
||||
6. Kindle 切换主题或方向后,应立即拉取对应背景并刷新
|
||||
7. 时钟的位置、尺寸和绘制参数由 `calendar` 的主题配置决定,Kindle 不自行决定
|
||||
|
||||
非目标:
|
||||
|
||||
- 不在 Kindle 上重新渲染整张页面
|
||||
- 不让 Kindle 维护主题路径规则
|
||||
- 不要求第一阶段就把现有导出脚本改成强制批量导出
|
||||
- 不让 Kindle 自行推导时钟区域布局
|
||||
- 不要求第一阶段就做“本地表盘素材包”体系
|
||||
|
||||
## 3. 设计原则
|
||||
|
||||
### 3.1 `calendar/` 是主题真相源
|
||||
### 3.1 `calendar/` 是单一真相源
|
||||
|
||||
主题系统的单一真相源放在 `calendar/` 侧。
|
||||
|
||||
@@ -47,7 +104,7 @@
|
||||
|
||||
- 一个主题清单文件,例如 `themes.json`
|
||||
- 每个主题自己的配置文件,例如 `default.json`、`paper.json`
|
||||
- 每个主题自己的背景图
|
||||
- 每个主题在不同方向下的背景图资源
|
||||
|
||||
其中 `themes.json` 至少描述:
|
||||
|
||||
@@ -55,6 +112,7 @@
|
||||
- 每个主题叫什么名字
|
||||
- 每个主题的配置 JSON 在哪里
|
||||
- 默认主题是谁
|
||||
- 默认方向是谁
|
||||
|
||||
这样做的好处是:
|
||||
|
||||
@@ -62,46 +120,56 @@
|
||||
- 新增主题时,Kindle 无需改代码里的路径规则
|
||||
- 网站预览和 Kindle 切换都依赖同一套主题元数据
|
||||
|
||||
这里再明确一下边界。
|
||||
### 3.2 `theme` 和 `orientation` 分开建模
|
||||
|
||||
远端主题配置只有两类:
|
||||
不建议把“横向主题”“纵向主题”作为主题名本身。
|
||||
|
||||
- `themes.json`
|
||||
- 每个主题自己的 JSON,例如 `themes/default.json`
|
||||
推荐模型是:
|
||||
|
||||
除此之外:
|
||||
- `theme`
|
||||
- `orientation`
|
||||
|
||||
- 背景图属于资源文件,不属于主题配置
|
||||
- Kindle 本地缓存属于运行时状态,不属于主题配置
|
||||
例如:
|
||||
|
||||
### 3.2 网站预览与导出解耦
|
||||
- `theme=default` + `orientation=portrait`
|
||||
- `theme=default` + `orientation=landscape`
|
||||
- `theme=paper` + `orientation=portrait`
|
||||
|
||||
主题预览只是网站访问时的交互能力,不应破坏当前导出主流程。
|
||||
这样更符合实际含义:
|
||||
|
||||
建议明确两条链路:
|
||||
- `theme` 代表视觉风格
|
||||
- `orientation` 代表设备摆放方向与对应布局
|
||||
|
||||
- 预览链路:用户访问 `/?mode=full&theme=<id>`,通过页面菜单切换主题
|
||||
- 导出链路:现有脚本继续生成默认背景图,保持兼容
|
||||
### 3.3 网站预览与导出解耦
|
||||
|
||||
主题和方向预览只是网站访问时的交互能力,不应破坏当前导出主流程。
|
||||
|
||||
当前已明确三条链路:
|
||||
|
||||
- 预览链路:用户访问 `/?mode=full&theme=<id>&orientation=<orientation>`,通过页面菜单切换主题和方向
|
||||
- 兼容导出链路:`export:background` 继续生成默认背景图,保持兼容
|
||||
- 批量导出链路:`export:themes` 一次性生成全部主题和方向背景
|
||||
|
||||
也就是说:
|
||||
|
||||
- 预览能力先落地
|
||||
- 当前 `kindlebg.png` 导出链路先不强制变化
|
||||
- 多主题导出作为后续增量能力接入
|
||||
- 预览能力已经落地
|
||||
- 当前 `kindlebg.png` 导出链路继续保留
|
||||
- 多主题多方向导出已经接入
|
||||
|
||||
### 3.3 Kindle 侧最简化
|
||||
### 3.4 Kindle 侧最简化
|
||||
|
||||
Kindle 侧只保留最小能力:
|
||||
|
||||
- 拉取背景图
|
||||
- 读取主题 JSON
|
||||
- 根据当前方向读取对应 variant
|
||||
- 按 JSON 提供的时钟参数绘制时钟
|
||||
|
||||
Kindle 不负责:
|
||||
|
||||
- 推导主题路径
|
||||
- 决定时钟区域坐标
|
||||
- 维护主题布局规则
|
||||
- 维护布局规则
|
||||
|
||||
推荐让 Kindle 只认识一个固定入口,例如:
|
||||
|
||||
@@ -112,14 +180,14 @@ https://shell.biboer.cn:20001/themes.json
|
||||
然后从这个 JSON 中知道:
|
||||
|
||||
- 当前有哪些主题
|
||||
- 默认主题和默认方向是什么
|
||||
- 每个主题的配置 JSON 在哪里
|
||||
- 切换到该主题时该去拉哪个背景图
|
||||
|
||||
### 3.4 当前时钟实现已经足够轻量
|
||||
### 3.5 当前时钟实现已经足够轻量
|
||||
|
||||
当前 Kindle 侧时钟是本地几何绘制,不依赖外部表盘或指针素材文件。
|
||||
|
||||
这意味着第一阶段主题切换只需要关注:
|
||||
这意味着第一阶段主题与方向切换只需要关注:
|
||||
|
||||
- 背景图 URL
|
||||
- 时钟区域位置和尺寸
|
||||
@@ -137,24 +205,25 @@ https://shell.biboer.cn:20001/themes.json
|
||||
{
|
||||
"updatedAt": "2026-03-16T10:00:00+08:00",
|
||||
"defaultThemeId": "default",
|
||||
"defaultOrientation": "portrait",
|
||||
"themes": [
|
||||
{
|
||||
"id": "default",
|
||||
"label": "Default",
|
||||
"configUrl": "https://shell.biboer.cn:20001/themes/default.json",
|
||||
"previewQuery": "?mode=full&theme=default"
|
||||
"orientations": ["portrait", "landscape"]
|
||||
},
|
||||
{
|
||||
"id": "paper",
|
||||
"label": "Paper",
|
||||
"configUrl": "https://shell.biboer.cn:20001/themes/paper.json",
|
||||
"previewQuery": "?mode=full&theme=paper"
|
||||
"orientations": ["portrait", "landscape"]
|
||||
},
|
||||
{
|
||||
"id": "classic",
|
||||
"label": "Classic",
|
||||
"configUrl": "https://shell.biboer.cn:20001/themes/classic.json",
|
||||
"previewQuery": "?mode=full&theme=classic"
|
||||
"orientations": ["portrait", "landscape"]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -167,33 +236,66 @@ https://shell.biboer.cn:20001/themes.json
|
||||
|
||||
### 4.2 主题配置 `<theme-id>.json`
|
||||
|
||||
每个主题再提供一份主题级配置,例如:
|
||||
每个主题提供一份主题级配置,内部包含两个方向的 variant,例如:
|
||||
|
||||
```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
|
||||
"variants": {
|
||||
"portrait": {
|
||||
"devicePlacement": "logo_bottom",
|
||||
"background": {
|
||||
"path": "themes/default/portrait/kindlebg.png",
|
||||
"url": "https://shell.biboer.cn:20001/themes/default/portrait/kindlebg.png",
|
||||
"refreshIntervalMinutes": 120
|
||||
},
|
||||
"clock": {
|
||||
"x": 347,
|
||||
"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
|
||||
}
|
||||
},
|
||||
"landscape": {
|
||||
"devicePlacement": "logo_right",
|
||||
"background": {
|
||||
"path": "themes/default/landscape/kindlebg.png",
|
||||
"url": "https://shell.biboer.cn:20001/themes/default/landscape/kindlebg.png",
|
||||
"refreshIntervalMinutes": 120
|
||||
},
|
||||
"clock": {
|
||||
"x": 795,
|
||||
"y": 659,
|
||||
"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,
|
||||
"rotationDegrees": 90
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -201,10 +303,26 @@ https://shell.biboer.cn:20001/themes.json
|
||||
说明:
|
||||
|
||||
- 背景图真实路径由主题配置提供,不在 Kindle 端拼接猜测
|
||||
- 时钟坐标和大小来自 `calendar` 中该主题的时钟占位,不允许 Kindle 任意改
|
||||
- 后续如果某个主题需要不同的时钟绘制参数,也由该 JSON 一起提供
|
||||
- `background.path` 是设备本地相对路径,用于优先读取已同步的本地背景
|
||||
- 每个方向都有自己的背景图和时钟区域
|
||||
- `landscape` 的 `clock` 已经是 Kindle 设备坐标,不再是网页坐标
|
||||
- `landscape` 的 `rotationDegrees=90` 表示 Kindle 本地绘制时钟时,表盘和指针再顺时针旋转 90 度
|
||||
- 时钟坐标和大小来自 `calendar` 中该主题该方向下的时钟占位,不允许 Kindle 任意改
|
||||
- 后续如果某个主题在不同方向下需要不同绘制参数,也由该 JSON 一起提供
|
||||
|
||||
### 4.3 Kindle 本地状态
|
||||
### 4.3 远端配置边界
|
||||
|
||||
远端主题配置只有两类:
|
||||
|
||||
- `themes.json`
|
||||
- 每个主题自己的 JSON,例如 `themes/default.json`
|
||||
|
||||
除此之外:
|
||||
|
||||
- 背景图属于资源文件,不属于主题配置
|
||||
- Kindle 本地缓存属于运行时状态,不属于主题配置
|
||||
|
||||
### 4.4 Kindle 本地状态
|
||||
|
||||
Kindle 本地只需要保存少量状态:
|
||||
|
||||
@@ -212,35 +330,67 @@ Kindle 本地只需要保存少量状态:
|
||||
/mnt/us/dashboard/local/theme.env
|
||||
/mnt/us/dashboard/local/state/themes.json
|
||||
/mnt/us/dashboard/local/state/current-theme.json
|
||||
/mnt/us/dashboard/local/state/theme-runtime.env
|
||||
/mnt/us/dashboard/local/state/background-updated-at
|
||||
```
|
||||
|
||||
其中:
|
||||
|
||||
- `theme.env` 只记录当前主题 ID
|
||||
- `theme.env` 记录当前 `THEME_ID` 和 `ORIENTATION`
|
||||
- `themes.json` 是最近一次同步到本地的主题清单缓存
|
||||
- `current-theme.json` 是当前主题配置缓存
|
||||
- `theme-runtime.env` 是 Kindle 实际消费的运行时快照,包含背景路径和时钟参数
|
||||
|
||||
这几项是 Kindle 本地运行状态,不属于远端主题配置。
|
||||
例如:
|
||||
|
||||
```sh
|
||||
export THEME_ID=default
|
||||
export ORIENTATION=portrait
|
||||
```
|
||||
|
||||
### 4.5 Kindle 本地主题资源
|
||||
|
||||
当前实现中,主题背景图会随部署一起同步到 Kindle:
|
||||
|
||||
```text
|
||||
/mnt/us/dashboard/themes/default/portrait/kindlebg.png
|
||||
/mnt/us/dashboard/themes/default/landscape/kindlebg.png
|
||||
/mnt/us/dashboard/themes/paper/portrait/kindlebg.png
|
||||
/mnt/us/dashboard/themes/paper/landscape/kindlebg.png
|
||||
/mnt/us/dashboard/themes/classic/portrait/kindlebg.png
|
||||
/mnt/us/dashboard/themes/classic/landscape/kindlebg.png
|
||||
```
|
||||
|
||||
Kindle 拉背景时的规则是:
|
||||
|
||||
1. 先读 `theme-runtime.env` 中的 `BACKGROUND_PATH`
|
||||
2. 如果本地对应文件存在,直接从 `/mnt/us/dashboard/themes/...` 拷贝
|
||||
3. 如果本地不存在,再回退到 `BACKGROUND_URL`
|
||||
|
||||
主题元数据同步的规则是:
|
||||
|
||||
1. 先读本地 `/mnt/us/dashboard/themes.json`
|
||||
2. 再读本地 `/mnt/us/dashboard/themes/<theme-id>.json`
|
||||
3. 本地 bundle 不存在时,才回退到远端 URL
|
||||
|
||||
## 5. `calendar/` 侧方案
|
||||
|
||||
### 5.1 网站访问时增加主题预览菜单
|
||||
### 5.1 网站访问时增加主题与方向预览菜单
|
||||
|
||||
主题预览菜单只出现在网站访问场景,不出现在背景截图结果里。
|
||||
预览菜单只出现在网站访问场景,不出现在背景截图结果里。
|
||||
|
||||
建议行为:
|
||||
|
||||
1. 用户访问 `/?mode=full` 时,在页面顶部显示一个可选主题菜单
|
||||
2. 切换菜单时更新当前页面的 `theme` 参数
|
||||
3. 菜单位置放在顶部任意不影响截图的位置即可
|
||||
4. 在 `mode=background` 下不显示该菜单,避免影响截图导出
|
||||
1. 用户访问 `/?mode=full` 时,在页面顶部显示两个可选菜单
|
||||
2. 一个菜单切换 `theme`
|
||||
3. 一个菜单切换 `orientation`
|
||||
4. 在 `mode=background` 下不显示这些菜单,避免影响截图导出
|
||||
|
||||
建议 URL 形态如下:
|
||||
|
||||
- `/?mode=full&theme=default`
|
||||
- `/?mode=full&theme=paper`
|
||||
- `/?mode=full&theme=classic`
|
||||
- `/?mode=full&theme=default&orientation=portrait`
|
||||
- `/?mode=full&theme=default&orientation=landscape`
|
||||
- `/?mode=full&theme=paper&orientation=portrait`
|
||||
|
||||
### 5.2 预览效果与 Kindle 效果对齐
|
||||
|
||||
@@ -249,8 +399,8 @@ Kindle 本地只需要保存少量状态:
|
||||
建议做到:
|
||||
|
||||
- 预览和导出使用同一套主题配置
|
||||
- 背景导出与预览使用同一套时钟占位信息
|
||||
- Kindle 侧按主题 JSON 中的时钟参数绘制,避免预览和实机错位
|
||||
- 预览和导出使用同一套方向布局配置
|
||||
- Kindle 侧按主题 JSON 中当前方向的参数绘制,避免预览和实机错位
|
||||
|
||||
这样评审主题时,看到的页面效果和 Kindle 最终效果才是一致的。
|
||||
|
||||
@@ -267,34 +417,41 @@ calendar/dist/clock-region.json
|
||||
兼容规则建议如下:
|
||||
|
||||
- 如果导出脚本没有显式传入 `theme`,默认导出 `default`
|
||||
- 如果导出脚本没有显式传入 `orientation`,默认导出 `portrait`
|
||||
- 现有 `export:background` 的行为保持不变
|
||||
- 先不强制要求所有主题都参与默认导出
|
||||
- 默认导出继续只产出 `default + portrait`
|
||||
|
||||
这样可以保证:
|
||||
|
||||
- 网站预览菜单先落地
|
||||
- 当前生产链路不被打断
|
||||
- Kindle 当前单主题使用方式继续可用
|
||||
- Kindle 当前单主题纵向使用方式继续可用
|
||||
|
||||
### 5.4 多主题导出作为附加能力
|
||||
### 5.4 多主题多方向导出已作为附加能力落地
|
||||
|
||||
当需要支持 Kindle 端多主题切换时,再增加多主题导出,例如:
|
||||
当前 `export:themes` 会生成如下产物:
|
||||
|
||||
```text
|
||||
calendar/dist/themes.json
|
||||
calendar/dist/themes/default.json
|
||||
calendar/dist/themes/default/kindlebg.png
|
||||
calendar/dist/themes/default/portrait/kindlebg.png
|
||||
calendar/dist/themes/default/landscape/kindlebg.png
|
||||
calendar/dist/themes/paper.json
|
||||
calendar/dist/themes/paper/kindlebg.png
|
||||
calendar/dist/themes/paper/portrait/kindlebg.png
|
||||
calendar/dist/themes/paper/landscape/kindlebg.png
|
||||
calendar/dist/themes/classic.json
|
||||
calendar/dist/themes/classic/kindlebg.png
|
||||
calendar/dist/themes/classic/portrait/kindlebg.png
|
||||
calendar/dist/themes/classic/landscape/kindlebg.png
|
||||
```
|
||||
|
||||
这里的关键点是:
|
||||
|
||||
- 原有 `calendar/dist/kindlebg.png` 继续保留
|
||||
- 多主题目录和 `themes.json` 是新增能力,不是替换能力
|
||||
- 主题路径管理由 `calendar` 决定,不在 Kindle 侧固化为固定模式
|
||||
- 多主题多方向目录和 `themes.json` 是新增能力,不是替换能力
|
||||
- 主题和方向的路径管理由 `calendar` 决定,不在 Kindle 侧固化为固定模式
|
||||
- 同步到 Kindle 时,会把整个 `calendar/dist/themes/` 目录一起带上
|
||||
- `landscape` 的网页先按 `1448x1072` 渲染,再顺时针旋转 90 度,写成 `1072x1448` 的 Kindle 设备图
|
||||
- 因此 `landscape` 的 `kindlebg.png` 是设备向产物,不是给桌面直接平铺预览的横图
|
||||
|
||||
## 6. Kindle 侧方案
|
||||
|
||||
@@ -310,29 +467,33 @@ themes.json 的 URL
|
||||
|
||||
- 被动同步:Kindle 每天拉取一次 `themes.json`
|
||||
- 主动同步:用户进入主题切换流程时,先即时拉取最新 `themes.json`
|
||||
- 如果设备上已经有本地同步的 `themes.json` 和主题 JSON,本地 bundle 优先
|
||||
|
||||
这样能兼顾:
|
||||
|
||||
- 平时低频更新
|
||||
- 切换主题时拿到最新主题清单
|
||||
|
||||
### 6.2 主题切换流程
|
||||
### 6.2 主题与方向切换流程
|
||||
|
||||
主题切换时建议执行以下流程:
|
||||
|
||||
1. 拉取最新 `themes.json`
|
||||
2. 根据用户选择的主题 ID 找到对应 `configUrl`
|
||||
3. 拉取该主题对应的 `<theme-id>.json`
|
||||
4. 将 `THEME_ID` 写入本地 `theme.env`
|
||||
5. 将主题 JSON 缓存在本地
|
||||
6. 立即拉取该主题背景图
|
||||
7. 立即执行一次全屏刷新
|
||||
8. 之后继续按当前分钟级时钟刷新逻辑运行
|
||||
4. 确定当前要使用的 `orientation`
|
||||
5. 从 `variants[orientation]` 里取出背景和时钟配置
|
||||
6. 将 `THEME_ID` 和 `ORIENTATION` 写入本地 `theme.env`
|
||||
7. 将主题 JSON 缓存在本地
|
||||
8. 优先读取本地 `themes/<theme>/<orientation>/kindlebg.png`
|
||||
9. 如果本地没有对应背景,再回退拉取 `background.url`
|
||||
10. 立即执行一次全屏刷新
|
||||
11. 之后继续按当前分钟级时钟刷新逻辑运行
|
||||
|
||||
这里有一个关键要求:
|
||||
这里有两个关键要求:
|
||||
|
||||
- 主题切换后,不等待下一个两小时周期
|
||||
- 而是立即拉取一次新主题背景
|
||||
- 主题或方向切换后,不等待下一个两小时周期
|
||||
- 而是立即拉取一次对应的新背景
|
||||
|
||||
### 6.3 时钟绘制保持现有模型
|
||||
|
||||
@@ -342,6 +503,7 @@ themes.json 的 URL
|
||||
|
||||
- 拉背景图片
|
||||
- 读取主题 JSON
|
||||
- 读取当前方向的 variant
|
||||
- 用本地 `lua + fbink` 画时钟
|
||||
|
||||
不需要在第一阶段增加:
|
||||
@@ -352,76 +514,97 @@ themes.json 的 URL
|
||||
|
||||
如果未来某个主题确实需要独立表盘素材,再在第二阶段扩展。
|
||||
|
||||
### 6.4 主题切换入口
|
||||
### 6.4 切换入口
|
||||
|
||||
入口建议做成“统一主题入口”,而不是在 KUAL 里硬编码每个主题项。
|
||||
当前已经有一个可直接 SSH 调用的入口:
|
||||
|
||||
目标交互是:
|
||||
```sh
|
||||
/mnt/us/dashboard/switch-theme.sh <theme-id> [orientation]
|
||||
```
|
||||
|
||||
例如:
|
||||
|
||||
```sh
|
||||
ssh kindle '/mnt/us/dashboard/switch-theme.sh default landscape'
|
||||
ssh kindle '/mnt/us/dashboard/switch-theme.sh paper portrait'
|
||||
```
|
||||
|
||||
如果本地刚改过页面样式,推荐先同步一次:
|
||||
|
||||
```sh
|
||||
sh scripts/sync-layered-clock-to-kindle.sh kindle
|
||||
```
|
||||
|
||||
KUAL 动态主题入口仍然是后续可选项,不是当前必需项。
|
||||
|
||||
如果后续要补 KUAL,目标交互仍然可以保持:
|
||||
|
||||
1. 用户点击“Theme”
|
||||
2. 设备根据 `themes.json` 获取当前可用主题清单
|
||||
3. 用户点击具体主题
|
||||
4. 立即切换到该主题
|
||||
|
||||
实现上可以接受两种方式:
|
||||
|
||||
- KUAL 能直接承载该交互,则由脚本在入口内完成
|
||||
- 如果 KUAL 不能直接动态展示,则由脚本先读取 `themes.json`,再生成或更新对应菜单
|
||||
3. 用户选择具体主题
|
||||
4. 用户选择 `portrait` 或 `landscape`
|
||||
5. 立即切换到该主题该方向
|
||||
|
||||
不管具体 UI 形态如何,数据契约都应保持一致:
|
||||
|
||||
- 主题列表来自 `themes.json`
|
||||
- 切换行为来自所选主题对应的 `<theme-id>.json`
|
||||
- 具体切换行为来自所选主题对应的 `<theme-id>.json`
|
||||
- 最终生效资源来自该主题该方向下的 variant
|
||||
|
||||
## 7. 分阶段落地
|
||||
## 7. 分阶段落地与当前进度
|
||||
|
||||
### 第一阶段:网站主题预览
|
||||
### 第一阶段:网站主题与方向预览(已完成)
|
||||
|
||||
目标:
|
||||
|
||||
- 新增 `theme` 参数
|
||||
- 增加顶部主题预览菜单
|
||||
- 新增 `orientation` 参数
|
||||
- 增加顶部预览菜单
|
||||
- 默认主题命名为 `default`
|
||||
- 新增 `paper` 和 `classic`
|
||||
- 每个主题都支持 `portrait` 和 `landscape`
|
||||
|
||||
结果:
|
||||
|
||||
- 用户可以在网站上预览三套主题
|
||||
- 用户可以在网站上预览三套主题的两种方向
|
||||
- `mode=background` 不显示预览控件
|
||||
- 现有截图导出流程保持不变
|
||||
|
||||
### 第二阶段:主题元数据发布
|
||||
### 第二阶段:主题元数据发布(已完成)
|
||||
|
||||
目标:
|
||||
|
||||
- `calendar/` 产出 `themes.json`
|
||||
- 每个主题产出自己的 `<theme-id>.json`
|
||||
- 每个主题有独立背景图 URL
|
||||
- 每个主题在两个方向下都有独立背景图 URL
|
||||
|
||||
结果:
|
||||
|
||||
- 主题列表、主题路径、时钟配置都由 `calendar/` 统一提供
|
||||
- Kindle 侧可以开始按 JSON 理解主题系统
|
||||
- 主题列表、方向列表、时钟配置都由 `calendar/` 统一提供
|
||||
- 主题配置里已同时提供 `background.path` 和 `background.url`
|
||||
|
||||
### 第三阶段:Kindle 端主题切换
|
||||
### 第三阶段:Kindle 端主题与方向切换(已完成)
|
||||
|
||||
目标:
|
||||
|
||||
- Kindle 能拉取 `themes.json`
|
||||
- Kindle 能按选择主题拉取对应的 `<theme-id>.json`
|
||||
- Kindle 能切换 `portrait` 和 `landscape`
|
||||
- 切换后立即拉取新背景并全屏刷新
|
||||
|
||||
结果:
|
||||
|
||||
- Kindle 端正式具备多主题切换能力
|
||||
- Kindle 侧仍保持最小职责
|
||||
- Kindle 端已具备多主题多方向切换能力
|
||||
- 切换后会立即刷新
|
||||
- SSH 命令切换已实机验证通过
|
||||
|
||||
### 第四阶段:按需扩展主题能力
|
||||
### 第四阶段:按需扩展主题能力(未开始)
|
||||
|
||||
只有在未来确实出现需求时,再考虑:
|
||||
|
||||
- 为某些主题提供独立表盘素材
|
||||
- 增加主题级本地资源同步
|
||||
- 增加更复杂的主题切换交互
|
||||
- 增加更复杂的切换交互
|
||||
|
||||
这一步不是当前必需项。
|
||||
|
||||
@@ -429,7 +612,7 @@ themes.json 的 URL
|
||||
|
||||
### 8.1 预览和实机效果偏差
|
||||
|
||||
如果预览和导出用的不是同一套主题配置,最终会出现:
|
||||
如果预览和导出用的不是同一套主题和方向配置,最终会出现:
|
||||
|
||||
- 网页看起来正确
|
||||
- Kindle 上时钟错位或背景不一致
|
||||
@@ -440,42 +623,53 @@ themes.json 的 URL
|
||||
- 导出
|
||||
- Kindle 时钟绘制
|
||||
|
||||
都依赖同一套主题元数据。
|
||||
都依赖同一套主题元数据和方向配置。
|
||||
|
||||
### 8.2 主题切换后的缓存问题
|
||||
### 8.2 方向切换后的缓存问题
|
||||
|
||||
如果主题切换后没有立即拉取新背景,Kindle 可能继续显示旧缓存。
|
||||
如果主题或方向切换后没有立即拉取新背景,Kindle 可能继续显示旧缓存。
|
||||
|
||||
因此切换主题时必须同时处理:
|
||||
因此切换时必须同时处理:
|
||||
|
||||
- 更新 `THEME_ID`
|
||||
- 更新 `ORIENTATION`
|
||||
- 拉取新的 `<theme-id>.json`
|
||||
- 拉取新的背景图
|
||||
- 拉取或读取当前方向对应的新背景图
|
||||
- 重置背景更新时间戳或直接覆盖缓存背景
|
||||
|
||||
如果设备本地没有同步主题背景,而远端对应 PNG 也还没发布完成,Kindle 可能拉到 HTML 或错误页而不是图片。
|
||||
|
||||
因此当前推荐做法是:
|
||||
|
||||
- 同步到 Kindle 时总是一起同步 `/mnt/us/dashboard/themes/`
|
||||
- 设备优先使用本地主题背景
|
||||
- 远端 `background.url` 只作为回退
|
||||
|
||||
### 8.3 主题清单缓存过旧
|
||||
|
||||
如果 Kindle 长时间只读本地缓存,可能看不到新主题。
|
||||
如果 Kindle 长时间只读本地缓存,可能看不到新主题或新方向配置。
|
||||
|
||||
因此建议:
|
||||
|
||||
- 日常低频同步一次 `themes.json`
|
||||
- 用户进入主题切换时再主动刷新一次
|
||||
- 用户进入切换流程时再主动刷新一次
|
||||
|
||||
## 9. 推荐结论
|
||||
## 9. 当前推荐结论
|
||||
|
||||
推荐采用下面这条路线:
|
||||
|
||||
1. 先在 `calendar` 网站上增加顶部主题预览菜单
|
||||
2. 维持当前默认背景导出链路不变
|
||||
3. 由 `calendar` 增量提供 `themes.json` 和主题级 `<theme-id>.json`
|
||||
4. Kindle 只读取固定位置的 `themes.json`
|
||||
5. 切换主题时立即拉取该主题配置和背景图,并继续使用现有本地时钟绘制
|
||||
1. 继续保留默认 `kindlebg.png` 导出链路,默认仍是 `default + portrait`
|
||||
2. 同时保留 `export:themes` 批量导出,作为多主题切换的资源来源
|
||||
3. 由 `calendar` 继续维护 `themes.json` 和主题级 `<theme-id>.json`
|
||||
4. 每个主题配置里同时提供 `portrait` 和 `landscape` 两套 variant
|
||||
5. Kindle 继续读取固定位置的 `themes.json`
|
||||
6. 切换主题或方向时优先使用本地同步的主题背景,并继续使用现有本地时钟绘制
|
||||
|
||||
这条路线的优点是:
|
||||
|
||||
- 不打断现有 `kindlebg.png` 生成流程
|
||||
- 主题路径和布局都由 `calendar` 统一管理
|
||||
- 主题和方向都由 `calendar` 统一管理
|
||||
- Kindle 侧实现最简化
|
||||
- 预览和实机显示可以基于同一套配置对齐
|
||||
- 即使远端主题图片还没发布完整,SSH 主题切换也能工作
|
||||
- 当前时钟实现不依赖表盘和指针素材,第一阶段改造成本低
|
||||
|
||||
Reference in New Issue
Block a user