feat: ClassIsland / ClassHelper 灵动岛提示词套件

- 重构版主提示词(14 parts,面向 ClassHelper 灵动岛重构)
- ClassIsland 全量规格提示词(20 parts,含分卷与逐章版本)
- 投喂指南、分卷、逐节文件
- 调研记录、一致性基线、生成与质检脚本
This commit is contained in:
ClassIsland Prompt Kit committed 2026-11-12 21:59:58 +08:00
commit 22c1784bab
117 files changed
+47759

No files matched your search

+149
View File
@@ -0,0 +1,149 @@
# analysis/refactor-ui.md —— ui-island Round 2 工作备注(Part 07)
- 任务:`task-7`(Round 2「重构 ClassHelper 灵动岛」的第 7 部分:岛结构与组件视觉规格)
- 产出:`parts-r/07-island-components.md`(CJK ≈ 7200 字,含 18 条验收标准)
- 工作方式:只读静态分析。未构建、未运行、未启动 Electron、未截图、未冒烟、未安装依赖、未改动 `repos/`。
- 口径:以 `analysis/50-refactor-brief.md` 与本轮 Lead 的两条补充为准(见 §3)。
## 1. 已读文件清单
### 1.1 ClassHelper 灵动岛渲染层(必读清单全部读完)
| 文件 | 读取范围 | 用途 |
|---|---|---|
| `packages/desktop-client/src/island/LayoutIslandApp.vue` | 全文 76 行 | 唯一渲染入口:fixed/custom/课件三选一、bridge 订阅 |
| `packages/desktop-client/src/island/IslandApp.vue` | 1–200、200–399、400–683(全文 683) | 经典模式:弹簧形变、胶囊/展开层、命中上报、触摸上报、模板结构 |
| `packages/desktop-client/src/island/CustomIslandRuntime.vue` | 全文 528 行 | 常驻模式:三页(compact/details/lesson)、测量、fitted 缩放、hit 上报、铃铛 |
| `packages/desktop-client/src/island/ComponentNode.vue` | 全文 456 行 | 组件渲染:组件契约→DOM/CSS、schedulePoints、hidden、style 计算 |
| `packages/desktop-client/src/island/ComponentIcon.vue` | 全文 36 行 | 14 类 kind 的 24×24 线性图标路径 |
| `packages/desktop-client/src/island/ClassicNotifications.vue` | 全文 234 行 | 消息详情卡/列表卡:head/badge/list-row/foot/按钮 |
| `packages/desktop-client/src/island/LessonReminderContent.vue` | 全文 318 行 | **5 段斜切遮罩的现有实现**(与 ClassIsland 参数一致)+ 课程提醒排版 |
| `packages/desktop-client/src/island/CoursewareTransfer.vue` | 全文 132 行 | 课件覆盖卡:尺寸/锚点/命中 |
| `packages/desktop-client/src/island/WeatherBrief.vue` | 仅列表(未细读内容) | 天气简报组件(需在实现时按 7.4.3 改写) |
| `packages/desktop-client/src/island/classic-island.css` | 全文 757 行 | WinIsland 经典:token/胶囊/展开卡/列表/按钮 |
| `packages/desktop-client/src/island/custom-island.css` | 全文 205 行 | 常驻卡/行/separated/铃铛/编辑面板 |
| `packages/desktop-client/src/island/custom-runtime.css` | 全文 255 行 | 常驻窗口/卡片/三页/行/尺寸/ClassIsland Fluent 化配色 |
| `packages/desktop-client/src/island/lesson-ending.css` | 全文 16 行 | 下课前徽标 30×30 正圆 |
| `packages/desktop-client/src/island/spring.ts` | 全文 115 行 | stiffness 0.10 / damping 0.68 / 换向 35% / 单帧 ≤20% / snap 0.05px |
| `packages/desktop-client/src/island/squircle.ts` | 全文 81 行 | 超椭圆 4.2 / 每角 14 段 / expandedRadius |
| `packages/desktop-client/src/island/main.ts` | 全文 30 行 | 入口、零依赖策略、applyMotionTokens 必须注入 |
### 1.2 主进程 / preload / shared
| 文件 | 读取范围 | 用途 |
|---|---|---|
| `packages/desktop-client/src/main/island.ts` | 1–140、400–659、1325–1710、1780–1900、2244–2343、grep 全文 | 窗口参数、几何(anchor/windowBox/windowBounds)、命中/触摸/失焦、淡入淡出、normalizeAppearance、常量 |
| `packages/desktop-client/src/preload/island.ts` | 全文 123 行 | contextBridge 白名单(getState/onAppearance/setHitRect/setTouchMode/...) |
| `packages/shared/src/island-layout.ts` | 全文 404 行 | 组件契约、CLASSISLAND_ISLAND_METRICS、默认方案、normalize 边界 |
| `packages/shared/src/constants.ts` | 240–369、379–470、grep | DEFAULT_ISLAND_APPEARANCE、RANGES、POSITIONS、STYLES、SIZE_DELTA、SHADOW_PAD、TYPE_SCALE、LIST_METRICS/islandListLayout |
| `packages/shared/src/motion.ts` | grep + 165–180 | `--ch-*` 令牌、EASE_OUT `[0.16,1,0.3,1]`、MOTION_DURATION 90/140/200/320/180 |
### 1.3 编辑器与设置页
| 文件 | 读取范围 | 用途 |
|---|---|---|
| `renderer/views/settings/IslandEditorView.vue` | 1–330 grep、542–860 | 编辑器结构:标签态/预览态、拖拽、抽屉、行表单、方案表单、组件库 |
| `renderer/views/settings/IslandSettingsView.vue` | grep 全文 | 外观设置项(高/宽/圆角/不透明度/字号/速度/主题色/视觉风格/位置/边距) |
| `renderer/components/IslandComponentSettings.vue` | grep 全文(307 行) | 组件设置页字段(时钟/倒计时/天气/文本/课程表/容器) |
| `renderer/components/IslandEditorNode.vue` | 全文 124 行 | 编辑器组件 chip、选中/container/drop 指示 CSS |
| `renderer/styles/island-editor.css` | grep 全文(8201 B) | 编辑器尺寸:行 54px、把手 24px、库项 76px、预览 padding |
### 1.4 文档与 ClassIsland 基准
| 文件 | 用途 |
|---|---|
| `repos/ClassHelper-master/docs/app/island.md` | 行为现状表(fixed vs custom 七种场景)、编辑流程、外观/输入、课程与课件 |
| `repos/ClassHelper-master/docs/dev/winisland-design-tokens.md` | 设计令牌、动画与命中约定、修改入口 |
| `repos/ClassIsland/AGENTS.md`、`repos/ClassHelper-master/AGENTS.md` | 纪律(注入) |
| 上一轮 `parts/04-main-window.md`、`parts/05-components.md` | ClassIsland 像素基准(本轮直接引用其行号证据) |
## 2. 关键参数表(ClassHelper 现状 → 目标)
### 2.1 窗口与几何
| 参数 | 现状 | 目标 | 证据 |
|---|---|---|---|
| 窗口标志 | transparent/frame:false/skipTaskbar/hasShadow:false/type:toolbar | 保持 | `main/island.ts:484-492, 504` |
| 可激活 | `focusable: true`(关掉会丢 mousedown) | 保持 | `:493-502` |
| 置顶 | `setAlwaysOnTop(x,'screen-saver')` + 全工作区可见 | 保持 | `:514-515` |
| 默认穿透 | `setIgnoreMouseEvents(true,{forward:true})` | 保持 | `:527` |
| 阴影留白 | `ISLAND_SHADOW_PAD = 10` | 保持 | `shared/constants.ts:351` |
| 边距 | `ISLAND_MARGIN = 8`,`marginX/marginY` 默认 8 | 保持 | `main/island.ts:2277`、`constants.ts:285-287` |
| 停靠 | 6 位置,居中不受 marginX | 保持 | `main/island.ts:1331-1351` |
| 多显示器 | `followCursorDisplay`(默认 false),60ms 轮询换屏 | 保持 | `:1354-1379` |
| fixed 包围盒 | 最大形态 + 2×pad,开合不动 | 保持;classisland 下高 = 40 或 40+气泡高 | `:1514-1553` |
| custom 包围盒 | `min(960, w) × min(640, h-marginY)` | 高度改为内容上限(`contentMaxHeight + 2*pad`) | `:1522-1529` |
| 触摸模式贴合 | `BLUR_GRACE_TOUCH_MS = 1200`,窗口只增不减 | 保持 | `:2287, 2297, 1560-1578` |
| 失焦宽限 | 500ms(非触摸) | 保持 | `:2287` |
| 命中限流 | 渲染 50ms + 主进程 60ms 兜底 | 保持 | `IslandApp.vue:417`、`main/island.ts:1829` |
| 心跳/重建 | 20s 超时、3 次 / 10min | 保持 | `main/island.ts:2315-2318` |
| 淡入淡出 | 步进 0.16 / 0.2 × 16ms | 保持 | `:1674-1710` |
| 指针避让淡化 | `residentFaded` → opacity × 0.05 | 保持 | `:1851-1877`、`island-layout.ts:35` |
### 2.2 行/背景/进度条(目标值,与 ClassIsland 对齐)
| 参数 | 目标 | ClassIsland 证据 |
|---|---|---|
| 行高 | 40 | `parts/04` §2.2(`MainWindowLine.axaml:16`) |
| 行内边距 | 左右 12 | `FluentTheme/Styles.axaml:110` |
| 行距 | 5 | `Models/Settings.cs:219` |
| 组件间距 | 12(6+6) | `MainWindow.axaml:396` |
| 圆角 | 8(0–20) | `Models/Settings.cs:183` |
| 背景不透明度 | 0.5(只作用背景) | `FluentTheme/Styles.axaml:44` |
| 行不透明度 | 1.0(0.1–1) | `MainWindowLineSettings.cs:42` |
| 描边 | 1px | `FluentTheme/Styles.axaml:47` |
| 阴影 | `0 4 8 2 #48000000` | `FluentTheme/Styles.axaml:49` |
| 字号 | 14 / 16 / 18 / 20 | `ThemeBase.axaml:32-35` |
| 进度条 | 3px | 本轮裁决 |
| 淡出比例 | 0.05 | `island-layout.ts:35` / `MainWindowLine.axaml:74` |
### 2.3 组件契约(ClassHelper 现状,必须沿用)
- `IslandComponentNode = { id, kind, settings, appearance, advanced, children }`(`island-layout.ts:77-108`)。
- `settings` 18 个字段:text/template/hour12/seconds/target/targetDate/countdownTitle/locationName/latitude/longitude/display/count/showPeriod/showProgress/direction/gap/interval/speed(`:80-99`)。
- `appearance` 14 个字段(`:61-76`);`advanced` 4 个字段(`:101-106`)。
- 规范化上限:12 行 / 200 节点 / 6 层 / 20 方案;`count 1–40`、`gap 0–64`、`interval 1–300`、`speed 1–200`、字号 8–96、radius 0–100(`:257-403`)。
- 默认节点值见 `:173-216`;默认方案见 `:217-255`(1 行 main:date/clock/schedule/messages;expandedRows:date/today-schedule)。
### 2.4 现有斜切遮罩参数(可直接复用)
`LessonReminderContent.vue:59-102`:`edges=[0,0.1,0.3,0.7,0.9,1]`(= 权重 0/0.1/0.2/0.4/0.2/0.1)、`offset = tan(30°)×40`、`delays = open?[0,90,120,90,0]:[120,90,0,90,120]`、`ease = 1-(1-p)^4 / p²`、总 480ms、兜底 600ms/speed。与 ClassIsland `SlantedMaskControl.cs:177-200` 完全对应 → 本轮只做"抽成共享组件"。
## 3. 本轮 Lead 口径更新(已回填)
1. **字段名**:`appearance.family: 'classisland' | 'winisland'`(不是改 `style`);`style` 继续表示 winisland 下的 black/glass/tinted 色调。
2. **默认值**:新安装 `classisland`;老用户升级保持 `winisland`(避免观感突变)→ 已写入 7.3.1 的迁移规则。
3. **fixed 重定义**:`classisland` 下 fixed = ClassIsland 风格信息行(1 行 = 日期 + 课程表、行高 40、圆角 8、背景 0.5、底部 3px 进度条;消息在同一行内展开气泡,保留既有业务规则);"胶囊 + 详情卡"只在 `winisland` 下保留 → 已重写 7.1.2、7.3.2/7.3.3、验收 2/3。
4. custom 仍用 schemes/rows/nodes 模型升级 → 7.2、7.4 覆盖。
5. **气泡不增高行**(第三条口径):`family='classisland'` 的消息气泡在固定 40px 行内渲染(遮罩/内容/进度都在 40 内),正文最多 2 行、超出省略;禁止把行高临时改到 48/56/64;`--ci-island-height: 40px` 不得被气泡改写;动画/遮罩按 ClassIsland 原版(360/120ms、文字 260/250ms、scale 1.1→1.0/750ms、退出 200ms)→ 已新增 **7.2.8 消息气泡**,并回改 7.1.2 A(窗口高恒 40+2×pad)、7.3.2(`targetSize` 高度恒 40、去掉高度弹簧)、7.4.12(容器高度按 family 分三种)、验收 2.1/2.2/5。
6. **custom 课程提醒接管规则**(第四条口径):custom 不因 in-class/prepare/break 临时接管整岛(课程进度由 `schedule` 组件展示);`ending` 仅以课程名右侧蓝色圆形秒数徽标显示;不新增"临时接管一行"行为;只有 fixed(classisland)显示完整课程提醒条 → 已写入 **7.3.3 fixed/custom 差异总表**(含课程接管),写明 `CustomIslandRuntime.vue:31-33` 的 `lesson` 计算改为恒 `null`、移除 `resident-lesson-page`,验收 9.1。
7. **`family` 只影响 fixed**(第五条口径,最终版):`classisland` 下 fixed = 信息行;`winisland` 下 fixed = 旧胶囊 + 详情卡;**custom 始终使用 ClassIsland 规格,不提供 winisland 回退**(custom 现有结构本就接近 ClassIsland,只做细化与像素对齐)→ 已回改:7.0 第 1/2/5 条、7.1.2 custom 段、7.2 标题、7.3 标题与 7.3.1(设置页在 custom 下隐藏"外观族/视觉风格")、7.3.2 custom 行、7.3.5 共享约束、验收 1.1/9;章节重排为 7.3.1 数据与开关 → 7.3.2 classisland → 7.3.3 差异总表 → 7.3.4 winisland → 7.3.5 共享约束。
> 注意:现有 `CustomIslandRuntime.vue:31-33` 的 `lesson` 会接管 custom 岛(prepare/on-class/break/in-class 都走 `resident-lesson-page`)。第六条口径要求**去掉**该接管,因此这是一处**行为变更**(不是保持代码现状),已在 7.3.3 写明具体改动点,需第 8 部分与第 12 部分验收同步。
>
> 另:**06/10 的双风格差异表需限定在 fixed**(Lead 要求)——我的 part 07 已按此表述;06(tokens)与 10(动画)若把 winisland 差异写到 custom 上,需要他们回改,不在本 part 范围。
## 4. 未决问题 / 需 Lead 或其它 part 确认
1. **`appearance.theme`(fluent/classic)与本文的衔接**:第 11 部分已列该字段,第 6 部分负责 token;本文只在 7.3.1 第 6 条要求"行背景/描边/阴影/遮罩参数随 theme 切换"。需要 part 06 给出 Fluent/Classic 两套实际色值(ClassIsland 侧 `SolidBackgroundFillColorSecondaryBrush` 等仍未被取色)。
2. **`scheme.rowHeight / componentGap / showProgress`**:第 13 部分(milestones)提到这三个 scheme 字段,第 5 部分负责 schema;本文已按"scheme 覆盖 > 外观族默认"写入 7.2.2,需与第 5 部分字段命名对齐。
3. **fixed(classisland)的消息卡形态**:本文规定"同一行内展开气泡 + 斜切遮罩 + 倒计时进度,保留 ClassHelper 暂存/紧急/叫人/已读/去重",但**气泡内的列表/按钮排布**归第 8 部分;需要第 8 部分确认是否复用现有 `ClassicNotifications.vue`(含 list-mode)还是新写 `ClassislandBubble.vue`。本文建议复用并加 `data-family` 样式覆盖。
4. **fixed 模式的"1 行默认组件"存放位置**:本文建议新建内置 fixed 方案(复用 `scheme.rows` 结构),但 `islandLayout` 现有结构里 fixed 模式不读 schemes(`LayoutIslandApp.vue:21` 只按 layout 分流)。需要第 5 部分决定:fixed 的默认行是"内置常量"还是"schemes 里的一条特殊方案"。
5. **`contentMaxHeight` 上报 IPC**:本文建议新增 `island:report-layout-metrics`,但第 4 部分(file-plan)负责 IPC 清单;需确认命名与白名单(`preload/island.ts:14-62`)。
6. **`windowBox()` 的 custom 高度**:现为 `min(640, h-marginY)`(`main/island.ts:1527`)。本文改为"内容上限",但内容上限需要渲染层测量后才知道;首帧仍用 640 兜底。需确认是否接受首帧到测量完成之间的一次 `setBounds`。
7. **触摸模式与固定包围盒的交互**:触摸模式窗口贴合岛体(`windowBox` 分支),classisland fixed 现在高度恒 40(气泡不再增高行),因此该冲突已消除;仅剩"行宽变化时触摸窗口只增不减"需在真机确认。
8. **`WeatherBrief.vue` 未细读**:只确认了文件存在与大小(2.9KB)。7.4.3 给出目标 DOM/尺寸,但**现有字段与数据形状需实现时先读该文件**(未决)。
9. **`lesson-ending.css` 徽标 30×30** 与 ClassIsland(课程名右侧蓝色圆形、剩余秒数 `-1`)一致,但 ClassIsland 的徽标尺寸未见源码定义(其计数徽标在 `LessonControlExpanded.axaml` 内)。本文按 ClassHelper 现值保留,若第 8 部分要改成 ClassIsland 尺寸需同步。
10. **`parts/04`/`parts/05` 的引用方式**:本文用行号引用上一轮 part 的结论(如 `parts/04` §2.2),最终汇总时需确认跨文件引用是否会被 Lead 改写为"直接证据路径"。
11. **`style` 旧值迁移**:现有 `ISLAND_STYLES = black|glass|tinted`;本轮不删,继续作为 winisland 色调。旧配置升级时 `family` 缺省 → winisland,`style` 原样保留,因此"毛玻璃用户"升级后外观不变(符合 Lead 口径)。
12. **编辑器选中框 1.5px 虚线**:ClassIsland 用 `Rectangle` + `StrokeDashArray="1,1.5"` + `StrokeThickness=1.5`(`repos/ClassIsland/ClassIsland/MainWindow.axaml:353-363`);CSS 的 `outline: dashed` 不支持自定义 dash 长度,实现需用 `background-image: repeating-linear-gradient` 或 SVG 边框。已在 7.5.2 写明"1.5px 虚线",但具体画法需在实现阶段定(P2 可接受近似)。
## 5. 自检
- [x] 只读:未构建、未运行、未启动 Electron、未截图、未冒烟、未安装依赖、未改 `repos/`。
- [x] 必读清单 18 个文件全部读过(`WeatherBrief.vue` 仅列目录,已在未决 §4.8 标注)。
- [x] 覆盖:窗口/几何(7.1)、行/背景/进度/遮罩/淡出/隐藏(7.2)、两套 family(7.3)、11 内置 + 3 消息入口 + 课件(7.4)、编辑器(7.5)、token(7.5.5)、验收(7.6)。
- [x] 每处像素值给 `packages/...:行号` 或 `repos/ClassIsland/...:行号`;无法确认标【推断】(如气泡宽度上限 720、ClassIsland 徽标尺寸)。
- [x] 已按 Lead 四条口径更新:`appearance.family` 字段名、fixed 的 classisland=信息行重定义、老用户保持 winisland、**气泡不增高行(40px 内)**、**custom 不被课程提醒接管**。
- [x] 中文祈使句,无"建议考虑"式模糊表述("建议"仅出现在给 Lead 的未决项里)。
- [x] CJK ≈ 8100 字(本轮无硬性字数要求,按上一轮 5000 标准超额满足)。