Files

94 lines
13 KiB
Markdown
Raw Permalink Normal View History

# analysis/refactor-editor.md — Round 2 / Part 09 工作底稿
负责人:windows(Part 09:编辑器与设置页重构)
模式:只读静态分析;未构建、未运行、未启动 Electron、未截图。禁止修改 `repos/`。
## 1. 已读文件清单(含范围)
### 1.1 ClassHelper(`repos/ClassHelper-master`)
| 文件 | 行数 | 读取范围 | 用途 |
|---|---|---|---|
| `packages/desktop-client/src/renderer/views/settings/IslandSettingsView.vue` | 512 | 全量 | 设置页现状:布局切换、外观参数、指针避让、保存/预览/恢复默认、半径同步 |
| `packages/desktop-client/src/renderer/views/settings/IslandEditorView.vue` | 861 | 全量 | 编辑器现状:方案栏、行、拖拽、四态预览、组件库、抽屉、保存队列、导入导出 |
| `packages/desktop-client/src/renderer/components/IslandComponentSettings.vue` | 307 | 全量 | 组件设置三页签现状与全部字段/范围 |
| `packages/desktop-client/src/renderer/components/IslandEditorNode.vue` | 124 | 全量 | 编辑态组件 chip/容器/落点高亮样式 |
| `packages/desktop-client/src/renderer/styles/island-editor.css` | 417 | 全量 | 编辑器全部尺寸:行高 54、间距 6、组件库 4 列、抽屉 360、响应式断点 |
| `packages/desktop-client/src/renderer/styles/index.css` | 892 | 令牌与 `.page/.page-title/.el-card` 相关段(21-54、103-131、186-204) | 设置页排版与颜色令牌 |
| `packages/desktop-client/src/renderer/views/settings/ReminderSettingsView.vue` | 153 | 全量 | 课程提醒现状(将迁入设置页) |
| `packages/shared/src/island-layout.ts` | 404 | 全量 | 组件/行/方案 schema、默认值、normalize 边界(12 行/200 节点/6 层/20 方案) |
| `packages/shared/src/constants.ts` | 680 | 255-344 | `DEFAULT_ISLAND_APPEARANCE`、`ISLAND_APPEARANCE_RANGES`、位置/风格标签、细缝与尺寸增量 |
| `packages/shared/src/types.ts` | 1874 | 1140-1199 | `IslandAppearance` 字段语义、`IslandPosition`/`IslandStyle` |
| `packages/desktop-client/src/main/island.ts` | 2445 | 255-384、2320-2445、grep 全文 | `editingLayout`、`syncCustomLayout`、`reportCustomSize`、IPC 注册、外观合并 16ms |
| `packages/desktop-client/src/main/ipc.ts` | 147 | 20-69 | `saveConfig` → `island.syncCustomLayout()` 链路 |
| `packages/desktop-client/src/main/config.ts` | 555 | 15-104、180-301、grep 430-455 | 配置字段、读盘 normalize、120ms 合并写盘、`island`/`islandLayout` 持久化 |
| `packages/desktop-client/src/preload/index.ts` | 101 | 20-99 | 主窗口桥接白名单(getConfig/saveConfig/islandSetAppearance/islandGetAppearance…) |
| `packages/desktop-client/src/preload/island.ts` | — | grep | 岛渲染桥:`getEditing/setEditing`、`getAppearance` |
| `packages/desktop-client/src/types/desktop.d.ts` | 294 | 140-199 | IPC 契约与“必须传纯对象”的注释 |
| `packages/desktop-client/src/renderer/router/index.ts` | 135 | 全量 | 岛设置/编辑器路由 |
| `packages/desktop-client/src/renderer/layouts/ClientLayout.vue` | 899 | 1-90 | 侧栏「灵动岛」项、`onIslandEditorOpen` → 编辑器 |
| `packages/desktop-client/src/island/LayoutIslandApp.vue` | 76 | 全量 | `onLayout` 热更新、fixed/custom 共用窗口 |
| `packages/desktop-client/src/island/CustomIslandRuntime.vue` | 520 | grep(class/style/ComponentNode) | 运行态行/间距/selected-id 接口 |
| `packages/desktop-client/src/main/smoke-layout.ts` | 443 | 全量 | 现有编辑器冒烟断言:DOM/文案/拖拽/方案/导入导出/预览约束 |
| `packages/desktop-client/src/main/smoke-resident.ts` / `smoke-quick.ts` | — | grep | 编辑器路由/编辑入口相关断言 |
| `docs/app/island.md` | 79 | 全量 | 编辑自定义方案、外观/输入、验证纪律 |
| `docs/dev/winisland-design-tokens.md` | 59 | 全量 | 经典/自定义几何令牌、动画与命中、修改入口 |
| `docs/dev/implementation.md` | 54 | 全量 | 岛与本机配置的现行约定 |
### 1.2 ClassIsland(`repos/ClassIsland`,版式参考)
| 文件 | 读取范围 | 用途 |
|---|---|---|
| `ClassIsland/Views/SettingPages/AppearanceSettingsPage.axaml` | 全量(上一轮已读) | 缩放/背景/不透明度/圆角/行距/分体/主题/字体/字号/字体色 |
| `ClassIsland/Views/SettingPages/ComponentsSettingsPage.axaml` | 全量(上一轮已读) | 方案栏、行列表、组件库、行设置、规则隐藏 |
| `ClassIsland/Controls/EditMode/EditModeView.axaml` | 1-180、280-420 | 外观抽屉、组件库抽屉、组件设置抽屉、行设置抽屉 |
| `ClassIsland/Controls/EditMode/EditableComponentsListBox.axaml` | 40-110、190-309 | 选择框 1.5px 虚线 1/1.5、容器虚线、添加组件按钮 32px、Spacing 12、行高 40 |
| `ClassIsland/MainWindow.axaml` | 180-249、340-379、380-449、449-561 | 编辑态选择框、组件 `Margin="6 0"`、行把手 20px、新主界面行按钮、容器行高 40 |
| `ClassIsland/Controls/MainWindowLine.axaml` | 全量 | `IslandContainerHeight=40`、行可见性/淡化规则 |
| `ClassIsland/XamlThemes/FluentTheme/Styles.axaml` | 195-239 | 行模板高度 40、内容 `Margin="12 0"`、`MinWidth=20` |
| `ClassIsland.Core/Controls/DrawerHost.axaml/.cs` | 上一轮已读 | 抽屉 250ms `cubic-bezier(0,0,0,1)`、Esc/遮罩关闭 |
| `ClassIsland/Models/Settings.cs` | 相关字段 | 课程提醒默认(60s 等)、外观默认值 |
## 2. 关键发现(写入 Part 09 的事实)
1. **`family` 是新增概念**:现有代码没有 `family`,也没有 `appearance.scale/theme/fontFamily/fontWeight/4 档字号/progressBar` 等 classisland 族字段;这些必须由 parts-r/05 落到 `IslandAppearance` 与 normalize,Part 09 已给建议字段名并标注“以 05 为准”。
2. **两套外观参数的现状**:`DEFAULT_ISLAND_APPEARANCE`(44/268/20/1.0/13px/1x/black/top-center/8/8)只服务 winisland 胶囊;`CLASSISLAND_ISLAND_METRICS`(rowHeight 40、horizontalPadding 12、radius 8、opacity 0.5、spacing 5、14/16/18/20)目前只用于 custom。fixed 在 classisland 族下的信息行需要新的外观字段,Part 09 用 `【新】` 标注。
3. **数据流已确认**:编辑器/设置页 → `window.desktop.saveConfig({islandLayout})` → `main/ipc.ts:34-45` 调 `island.syncCustomLayout()` → `main/island.ts:320-338` 向岛渲染进程 `send('island:layout')` → `LayoutIslandApp.vue:35-51` 热更新。外观是独立通道:`island:set-appearance`(16ms 合并)→ `island.setAppearance`,`saveConfig({island})` 才落盘。
4. **保存语义**:编辑器每次改动即 `saveConfig`,盘写有 120ms 合并窗口(`main/config.ts:252-298`);保存成功 ≈ 已写入 `islandLayout`,但 `layout` 只在「应用并返回」/设置页选择时切 `custom`。
5. **`editingLayout` 是死标志**:`main/island.ts:258` 声明后**全仓库没有任何写入点**,`getEditingLayout()` 恒为 false,`island:set-editing` 只会触发打开主窗口编辑器。Part 09 已注明“编辑模式实际由主窗口路由页承担”,重构需清理或补全该标志(属 stack/part 04,不属本 part 改动)。
6. **现有编辑器 DOM/文案是测试契约**:`smoke-layout.ts` 断言 `.component-library` 11 项、「新增行」、`data-action=wrap`、三页签 `.el-tabs__item`、`.preview-canvas/.preview-toolbar` 不遮挡、方案新建/重置/删除/导入导出、拖拽跨行、无 iframe/`.layout-editor`。Part 09 已将其列为“不得破坏”,并注明页签 3→4 需 part 11 同步更新测试。
7. **设置页同步规则**:现有代码在 `layout=custom` 时把外观圆角同步进当前方案并落盘(`IslandSettingsView.vue:113-122`);Part 09 扩展为圆角/不透明度/行距三项同步。
8. **课程提醒位置**:目前独立在 `/settings/reminder`(`ReminderSettingsView.vue`),字段是 `islandLayout.lessonReminders`(7 个字段,默认 60/60 秒)。Part 09 建议迁入设置页并让提醒页只留跳转,避免双写。
9. **ClassIsland 编辑模式数值**:选择框 `1.5px` 虚线 `1,1.5`、opacity `.75`(`EditableComponentsListBox.axaml:225-251`、`MainWindow.axaml:353-366`);组件 `Margin="6 0"`(`MainWindow.axaml:396`、`:546`);行内容 `Margin="12 0"`、`MinWidth 20`、行高 40(`FluentTheme/Styles.axaml:203-232`);编辑态组件列表 Spacing 12(`EditableComponentsListBox.axaml:53`);添加组件按钮 32px/图标 20(`:55-60`);「新主界面行」按钮 E00D(`MainWindow.axaml:449-455`);行设置抽屉内容(`EditModeView.axaml:314-405`)。
10. **不打扰纪律**:编辑预览不得创建额外桌面窗口(`docs/app/island.md:47`);验收必须无头,只有显式 `--visual` 才做视觉验证(`docs/app/island.md:75-79`)。
## 3. 现状 → 目标改造对照
| 区域 | 现状 | 目标(Part 09 规格) |
|---|---|---|
| 设置页结构 | 布局卡 + 外观参数卡 + 指针避让;无 family/课程提醒 | 页头徽标 + 布局卡 + family 分段 + 两族参数 + 课程提醒卡 + 指针卡 + 操作条 |
| family | 无 | `islandAppearance.family: classisland\|winisland`;新装 classisland、老配置迁移 winisland;custom 下禁选 |
| fixed 外观 | 胶囊 + 详情卡(唯一形态) | classisland 族 = 信息行(40/8/0.5/3px 进度条),winisland 族 = 胶囊;参数分两套 |
| 外观字段 | height/width/radius/opacity/accent/fontSize/animations/speed/position/alwaysOnTop/style/idleSliver/marginX/marginY/followCursorDisplay | 新增 scale/theme/fontFamily/fontWeight/4 档字号/foreground/spacing/separated/progressBar(以 part 05 为准) |
| 课程提醒 | 独立 `ReminderSettingsView` | 迁入设置页;提醒页改为跳转提示 |
| 编辑器行高 | 标签态 54、预览 44、行距固定 6 | 标签态 46、预览 40、行距=scheme.spacing,组件外边距 6 |
| 选中框 | 选中色块背景 + 边框 | 1.5px 虚线 1/1.5、opacity .75;容器未选中虚线 |
| 组件设置 | 内容/外观/高级 三页签 | 内容/外观/尺寸/隐藏条件 四页签 |
| 抽屉 | 360px、非模态、默认动画 | 保留,动画统一 250ms `cubic-bezier(0,0,0,1)` |
| 新增行入口 | 工具条「新增行」 | 保留 + 行列表末尾居中「新增行」(E00D/32px) |
| 预览/编辑模式 | 页面内 live preview + 缩放 0.3–1.5 | 保留;补 Esc/Delete/Ctrl+D 键盘、真岛热更新说明 |
| 属性同步 | 圆角同步 current scheme | 圆角/不透明度/行距三项同步(custom) |
| 迁移 | 无 `family` | 老用户默认 winisland;`islandLayout.version=2` 由 part 05 定 |
## 4. 未决问题 / 需 Lead 或其它 part 确认
1. **新增字段的最终命名与归一化边界**必须由 parts-r/05(数据契约)定稿:`family`、`scale`、`theme`、`fontFamily`、`fontWeight`、`secondaryFontSize/bodyFontSize/emphasizedFontSize/largeFontSize`、`foreground`、`spacing`、`separated`、`progressBar`。Part 09 已给建议名与默认值,若 05 改名,本 part 需同步替换。
2. **`family` 对 custom 的作用**:本 part 按“custom 始终 ClassIsland 规格,family 仅影响 fixed”写;若 Lead/part 07 认为 custom 也应支持 winisland 胶囊化,需要重新定义(会增加渲染分支,不建议)。
3. **fixed classisland 信息行的组件数据从哪来**:默认 1 行 = 日期 + 课程表(brief §2.3),但 fixed 不使用 `schemes/rows/nodes`。Part 07 需要定义 fixed 行的内置组件集合与是否允许用户通过“编辑固定行”调整;Part 09 只在设置页给静态缩略示意图,未定义编辑入口。若需要可编辑,应在 parts-r/05 增 `fixedRows` 或在 07 说明“固定行不可编辑”。
4. **课程提醒迁入设置页**与 `/settings/reminder` 的去留:Part 09 建议迁移+跳转;若 Lead/UI 决定保留原页并复制控件,会出现双写风险,需要明确唯一数据源。
5. **冒烟测试更新**:组件设置页签 3→4、设置页新增 family/课程提醒卡、行高/间距调整都会改变现有 `smoke-layout.ts` 断言;这些测试更新属 parts-r/11,需要与本 part 同 PR 落地(Part 09 已列清楚哪些文案/DOM 必须保留)。
6. **`editingLayout` 死标志**:建议 part 04 决定删除或补全(若保留,需要 `island:set-editing` 真正进入岛内编辑态,涉及岛窗口交互,超出本 part 范围)。
7. **字体/字重数据来源**:classisland 族需要字体列表(系统字体或内置 HarmonyOS Sans)。Part 09 只给出控件与默认,具体字体资源属 parts-r/15 资源清单/06 tokens。
8. **`progressBar` 的显示条件**:classisland fixed 行底部 3px 进度条是否只在“有当前课程”时显示、课间是否隐藏,属 parts-r/07/08 渲染规则;Part 09 只给设置项(显示开关/高度/颜色)与默认值。
9. **主题明暗**:岛主题独立于主窗口 `config.theme`(建议 `appearance.theme`),但 ClassHelper 渲染层目前是否已有暗/亮 CSS 变量切换需 parts-r/06/07 确认;若无,本 part 的明暗项需要延后到 tokens 落地。
10. **未读文件**:`IslandApp.vue`、`CustomIslandRuntime.vue`、`ComponentNode.vue` 的渲染细节未全读(属 parts-r/07);`IslandComponentSettings` 的组件渲染契约以 shared schema 为准,已在本 part 表格覆盖字段,但“控件外的可视化效果”需 07 确认。