feat: ClassIsland / ClassHelper 灵动岛提示词套件
- 重构版主提示词(14 parts,面向 ClassHelper 灵动岛重构) - ClassIsland 全量规格提示词(20 parts,含分卷与逐章版本) - 投喂指南、分卷、逐节文件 - 调研记录、一致性基线、生成与质检脚本
This commit is contained in:
commit
22c1784bab
117 files changed
+47759
No files matched your search
@@ -0,0 +1,104 @@
|
||||
# 团队总简报:反推 ClassIsland 的「给 ChatGPT 的完整实现提示词」
|
||||
|
||||
## 0. 最终交付物
|
||||
- 主交付:`D:\clword\ClassIsland-给ChatGPT的完整提示词.md`(简体中文,由 Lead 汇总各 part 而成)。
|
||||
- 该文件是**一份可以直接粘贴给 ChatGPT 的提示词**:用户角色是「实现者」,提示词要求 ChatGPT 从零实现一个 ClassIsland 等价的桌面课表信息工具,技术栈采用 ClassHelper 的 Electron + Vue 3 技术栈(见 §4)。
|
||||
- 备选交付:`out/` 下的分卷版(若有时间)。
|
||||
|
||||
## 1. 任务定义
|
||||
1. 深度研读 `repos/ClassIsland`(C# / .NET 8 / Avalonia / FluentAvalonia,ClassIsland v2.x 源码,含 MainWindow、Core、Shared、PluginSdk、平台层等)。
|
||||
2. 深度研读 `repos/ClassHelper-master`(TypeScript / pnpm monorepo / Electron 44 / Vue 3.5 / Element Plus / Pinia / Vite 8 / Socket.IO / Prisma,含 desktop-client 的「灵动岛」实现)。
|
||||
3. 把 ClassIsland 的**全部功能、全部界面、全部动画、全部像素级参数**反写成一份超详细的实现规格提示词;实现技术栈按 ClassHelper 的栈来写(必要处给出等价映射方案)。
|
||||
4. 输出不是分析报告,而是**祈使句提示词**:面向 ChatGPT 的实现任务书,要求「必须/不得/应当」,包含具体数值、文件结构、数据结构、交互、动画曲线、验收清单。
|
||||
|
||||
## 2. 硬性纪律(极重要)
|
||||
- **绝对禁止**构建、运行、启动、截图、冒烟、smoke/verify 任何程序;禁止 `dotnet build`、`dotnet run`、`pnpm dev`、`electron`、`npm`、任何会弹窗或占用屏幕的命令。用户明确要求「不要打扰我,后台做好」。
|
||||
- 只允许静态分析:读文件(read 工具,UTF-8)、grep、glob、读取图片尺寸等不启动 UI 的操作。可以运行纯文本处理命令(如读取文件行数),但不得执行安装/构建/启动。
|
||||
- **不要修改 `repos/` 下任何文件**。只在 `analysis/`、`parts/`、`out/` 写文件;不要动别人的文件。
|
||||
- 不要提交、不要联网克隆新仓库(需要的信息用已有文件 + 必要时 web_fetch 官方文档/README)。
|
||||
|
||||
## 3. 每个 part 文件的格式规范
|
||||
文件路径:`parts/NN-名称.md`。文件内容仅包含该部分的正文,标题从 `## N. 标题` 开始(一级标题由 Lead 汇总时生成)。
|
||||
|
||||
写作要求:
|
||||
- 简体中文;技术名词保留英文原名(如 FluentAvalonia、TransparencyLevelHint、Storyboard)。
|
||||
- **面向 ChatGPT 的实现指令**:用「必须 / 不得 / 应当 / 需要」等祈使句;不要写「本项目如何如何」的旁观式分析。
|
||||
- 每个视觉/行为参数尽量给**确切数值**:宽高、Margin、Padding、CornerRadius、FontSize、FontWeight、颜色(HEX/资源名)、透明度、动画 Duration(毫秒)、缓动曲线(如 CubicEaseOut、0.65,0,0.35,1.0)、层级(ZIndex/窗口层级)、DPI/缩放规则。
|
||||
- 每个数值/行为尽量标注来源:`repos/ClassIsland/ClassIsland/MainWindow.axaml:282` 这种相对路径:行号;无法从源码确认的写【推断】。
|
||||
- 每个功能点建议覆盖:目的、默认值/默认行为、触发条件、UI 表现(像素级)、动画、边界/异常情况、数据结构(JSON 字段)、与其他模块的联动、验收标准。
|
||||
- 参照现有代码里的命名(MainWindow、MainWindowLine、Component、Profile、ClassPlan、TimeLayout、Notification、Automation、Ruleset、XamlTheme、Settings 等)。
|
||||
- 篇幅:不设上限,宁详勿略;但禁止空洞套话。目标每个 part 至少 3000 中文字,核心技术 part 6000+。
|
||||
|
||||
## 4. 技术栈事实(ClassHelper,实现时采用)
|
||||
来自 `repos/ClassHelper-master/package.json`、`pnpm-workspace.yaml`、各 `packages/*/package.json`、`AGENTS.md`:
|
||||
- pnpm@11.8.0 monorepo,Node >= 20.19;根 package.json 为版本单一来源。
|
||||
- 包:`packages/shared`(三端共享类型/常量/权限/动效/岛方案与课件契约)、`packages/ui`(共享 Vue 控件、主题、`tokens.css`)、`packages/desktop-client`(Electron 主进程 + preload + 主窗口渲染进程 + 独立灵动岛渲染进程)、`packages/server`(Express 5 + Prisma 7 + Socket.IO,API 前缀 `/api`)、`packages/web-admin`(Vue 管理端 PWA)。
|
||||
- desktop-client 依赖:Electron ^44.3.0、Vue ^3.5.42、Element Plus ^2.14.5、Pinia ^4.0.3、Vue Router ^5.3.1、axios、socket.io-client、Vite ^8.3.0、TypeScript ~5.9.3、electron-builder 26。
|
||||
- 灵动岛实现要点(必须复用/对齐):独立 `island.html` 渲染入口 + 独立 BrowserWindow(透明、无边框、置顶、点击穿透、失焦宽限期等,见 `src/main/island.ts`);`squircle.ts` 连续圆角(超椭圆指数 4.2、每角 14 段);`spring.ts` 弹簧动画(stiffness 0.10、damping 0.68、换向动量保留 35%、单帧位移 ≤ 剩余距离 20%、snap 阈值 0.05px、60fps 帧单位);`classic-island.css` / `custom-island.css`;配置 `config.json`(主进程 `config.ts`);`renderer/composables/motion.ts`;`renderer/styles/index.css` 的 CSS token;IPC 走 contextBridge 白名单(`src/preload/*`)。
|
||||
- 安全约定:preload 只暴露 contextBridge 白名单、不暴露 ipcRenderer;保留 CSP;离线缓存隔离;不使用 `setBackgroundMaterial()` 破坏逐像素透明。
|
||||
- 后端在本任务中**不要求**(ClassIsland 是本地单机应用);如需数据层,优先采用本地文件 + IndexedDB(对齐 ClassHelper 客户端离线缓存模式),不要引入服务器依赖。若必须用到(可选),说明为可裁剪模块。
|
||||
|
||||
## 5. 术语表(统一用词)
|
||||
- 主界面 / 岛:ClassIsland 的悬浮课表窗口(MainWindow,可拆分为多行「岛」)。
|
||||
- 主界面行:MainWindowLine(一行;含组件集合、背景、进度条、遮罩、提醒气泡)。
|
||||
- 组件:Component(日期、时间、倒计时、课程表、天气、文本、滚动、堆叠、分组、分隔线等)。
|
||||
- 档案:Profile(一套课表/时间表/科目的配置,JSON 文件)。
|
||||
- 课表:ClassPlan(某周的每日课程);时间表:TimeLayout(时间点 TimeLayoutItem 列表)。
|
||||
- 时间点:TimeLayoutItem,类型 上课/课间/分割线/行动(OnClass/Breaking/Separator/Action)。
|
||||
- 提醒:Notification(NotificationRequest/NotificationProvider/NotificationHostService);强提醒:提醒特效(Topmost 全屏遮罩)。
|
||||
- 自动化:Automation(触发器 Trigger + 动作 Action + 规则集 Ruleset/Rule)。
|
||||
- 主题:XamlTheme(ClassIsland 用 XAML 资源字典;实现时映射为 CSS 变量 + 主题包,见 part 9)。
|
||||
- 设置:Settings(`Settings.json`,所有字段有默认值)。
|
||||
- 插件:Plugin(ClassIsland 的 .cipx/DLL 扩展;实现时映射为 npm 包/动态模块,见 part 12)。
|
||||
- 提醒优先级:NotificationPriority(Low/Medium/High 等,按源码)。
|
||||
|
||||
## 6. 分工与 part 对应
|
||||
| Part | 内容 | 负责人 | 文件 |
|
||||
|---|---|---|---|
|
||||
| 01 | 总纲:产品定位、目标用户、体验原则、总体架构图 | Lead | parts/01-overview.md |
|
||||
| 02 | 技术栈与工程结构(ClassHelper 栈、目录、进程模型、构建) | stack | parts/02-tech-stack.md |
|
||||
| 03 | 设计系统 tokens(颜色/字体/字号/圆角/间距/阴影/层级/动效曲线/深浅色) | design | parts/03-design-tokens.md |
|
||||
| 04 | 主界面(岛)像素级规格:窗口、行、背景、进度、遮罩、编辑模式、隐藏/穿透、多显示器、右键菜单 | ui-island | parts/04-main-window.md |
|
||||
| 05 | 组件系统:全部组件逐个规格(含设置项、布局、动画) | ui-island | parts/05-components.md |
|
||||
| 06 | 课程表/时间表/档案/科目/周次/调课/导入导出 | features | parts/06-schedule-profile.md |
|
||||
| 07 | 提醒系统:提供者、队列、气泡、强提醒、音效、TTS、天气提醒 | features | parts/07-notifications.md |
|
||||
| 08 | 自动化:触发器/动作/规则集/条件 | features | parts/08-automation.md |
|
||||
| 09 | 主题系统:内置主题、主题包格式、壁纸取色、主题编辑器 | design | parts/09-themes.md |
|
||||
| 10 | 设置中心:页面树、每页控件与默认值、搜索、缓存策略 | windows | parts/10-settings.md |
|
||||
| 11 | 其他窗口:启动闪屏、欢迎向导 OOBE、通知中心、崩溃/恢复、数据迁移、更新、教程、作者/致谢等 | windows | parts/11-other-windows.md |
|
||||
| 12 | 插件系统 + 多进程 IPC + 单实例 + 自动更新(ClassHelper 映射) | stack | parts/12-plugins-ipc.md |
|
||||
| 13 | 数据模型与存储:Settings/Profile/ClassPlan/TimeLayout/Automation/Notification JSON schema、备份、迁移、路径 | stack | parts/13-data-storage.md |
|
||||
| 14 | 动画与动效总表:每个动画的触发、属性、时长、曲线、层级 | design | parts/14-animations.md |
|
||||
| 15 | 资源清单:图标、字体、音效、图片、本地化、主题预览 | design | parts/15-assets.md |
|
||||
| 16 | 质量门禁与验收清单 | Lead | parts/16-acceptance.md |
|
||||
| 17 | 开发里程碑与实现顺序 | Lead | parts/17-milestones.md |
|
||||
| 18 | 禁止事项与边界(禁止冒烟、性能底线等) | Lead | parts/18-forbidden.md |
|
||||
|
||||
## 7. 产出质量自检(提交前逐条确认)
|
||||
- [ ] 所有关键数值有来源或标注【推断】,没有编造「看起来很精确」的数字。
|
||||
- [ ] 覆盖了该 part 对应源码目录的全部主要文件(列出已读文件清单在 `analysis/` 备注中)。
|
||||
- [ ] 用词遵循术语表;part 之间不冲突(例如窗口圆角、动画时长、颜色 token 名)。
|
||||
- [ ] 有「验收标准」小节:实现者如何自查这一部分做对了。
|
||||
- [ ] 没有出现「我们可以/建议考虑」这类模糊表述。
|
||||
- [ ] 没有运行任何 UI/构建命令。
|
||||
|
||||
## 8. 参考入口(先读这些)
|
||||
ClassIsland:
|
||||
- `repos/ClassIsland/README.md`、`repos/ClassIsland/AGENTS.md`、`repos/ClassIsland/doc/`(文档)
|
||||
- `repos/ClassIsland/ClassIsland/MainWindow.axaml`(686 行,主界面)、`MainWindow.axaml.cs`
|
||||
- `repos/ClassIsland/ClassIsland/Models/Settings.cs`(全部设置默认值)
|
||||
- `repos/ClassIsland/ClassIsland/Controls/MainWindowLine.axaml`
|
||||
- `repos/ClassIsland/ClassIsland/XamlThemes/{FluentTheme,ClassicTheme}/`(主题与样式)
|
||||
- `repos/ClassIsland/ClassIsland/Controls/Components/`(组件)
|
||||
- `repos/ClassIsland/ClassIsland/Views/`(全部窗口)
|
||||
- `repos/ClassIsland/ClassIsland.Core/`(框架、抽象、控件、服务)
|
||||
- `repos/ClassIsland/ClassIsland/Assets/`(图标/字体/音效/教程/Localization)
|
||||
ClassHelper:
|
||||
- `repos/ClassHelper-master/AGENTS.md`、`README.md`、`docs/`
|
||||
- `repos/ClassHelper-master/packages/desktop-client/src/main/island.ts`、`config.ts`、`ipc.ts`
|
||||
- `repos/ClassHelper-master/packages/desktop-client/src/island/*`(IslandApp.vue、spring.ts、squircle.ts、classic-island.css)
|
||||
- `repos/ClassHelper-master/packages/desktop-client/src/preload/*`、`src/renderer/**`
|
||||
- `repos/ClassHelper-master/packages/ui/src/tokens.css`、`theme.css`
|
||||
- `repos/ClassHelper-master/packages/desktop-client/src/renderer/composables/motion.ts`
|
||||
|
||||
提示:中文文件是 UTF-8;PowerShell `Get-Content` 可能乱码,请用 `read` 工具读文本。
|
||||
@@ -0,0 +1,59 @@
|
||||
# 一致性基准(Lead 已核对的 canonical 数值,供各 part 对齐与 Lead 审校)
|
||||
|
||||
> 本文件由 Lead 从源码核对;队友的 part 若与本文件冲突,以源码为准并在交付说明中指出;Lead 汇总时统一。
|
||||
|
||||
## 主界面(Fluent 主题)
|
||||
- `IslandContainerHeight = 40`(行内容/背景高度,FluentTheme/Styles.axaml:65)
|
||||
- 行内容区 `MinWidth=20`,`Margin="12 0"`(FluentTheme/Styles.axaml:107-110)
|
||||
- 行背景:`BorderThickness=1`,背景 `SolidBackgroundFillColorSecondaryBrush`,边框 `ControlElevationBorderBrush`,阴影 `0 4 8 2 #48000000`,圆角 = RadiusX(默认 8,`ConverterParameter=1.0`)(FluentTheme/Styles.axaml:40-50)
|
||||
- 背景过渡:`Opacity 100ms`、`BackgroundWidth 300ms cubic-bezier(0.65, 0, 0.35, 1.0)`(FluentTheme/Styles.axaml:268-269;MainWindow.axaml:197-198)
|
||||
- Classic 主题:`BackgroundWidth 550ms cubic-bezier(0.00, 1.00, 0.50, 1.10)`、`Opacity 100ms`(ClassicTheme/Styles.axaml:206-207)
|
||||
- 组件外边距:根组件 `Margin="6 0"`(MainWindow.axaml:396)
|
||||
- 行垂直间距 = `MainWindowLineVerticalMargin` 默认 5(Settings.cs:219;MainWindow.axaml:344)
|
||||
- 选择框(编辑模式):`StrokeThickness=1.5`、`StrokeDashArray="1, 1.5"`、`Opacity=0.75`、`StrokeLineCap=Round`、`StrokeJoin=Bevel`(MainWindow.axaml:353-363)
|
||||
- 编辑模式窗口:背景 `SmokeFillColorDefaultBrush`,`TransparencyLevelHint=AcrylicBlur,Transparent`;窗口模式窗口 `SystemDecorations=Full` 等(MainWindow.axaml:165-191)
|
||||
- 主窗口:`ShowActivated=False`、`TransparencyBackgroundFallback=Transparent`、默认 `Height=1`(自适应)、`CanResize/Maximize/Minimize=False`、`SystemDecorations=None`(MainWindow.axaml:8,32,168-176)
|
||||
|
||||
## 窗口与设置默认值(ClassIsland/Models/Settings.cs)
|
||||
- `Theme=2`(跟随系统;0 亮 1 暗 2 跟随); `PrimaryColor=DeepSkyBlue`; `SecondaryColor=Aquamarine`
|
||||
- `WindowDockingLocation=1`(中上侧;0 左上 1 中上 2 右上 3 左下 4 中下 5 右下)
|
||||
- `WindowDockingOffsetX/Y=0`; `WindowDockingMonitorIndex=0`; `WindowLayer=1`; `IsMouseClickingEnabled=false`
|
||||
- `Opacity=0.5`; `Scale=1.0`; `RadiusX=RadiusY=8.0`; `MainWindowFont=默认`; `MainWindowFontWeight2=Medium(500)`
|
||||
- 字号:Secondary 14 / Body 16 / Emphasized 18 / Large 20
|
||||
- `MainWindowLineVerticalMargin=5`; `IsIslandSeperated=false`; `ReduceProgressAccuracy=true`
|
||||
- `IsMainWindowVisible=true`; `HideOnClass=false`; `HideOnMaxWindow=false`; `HideOnFullscreen=false`
|
||||
- `ClassPrepareNotifySeconds=60`; `IsClassPrepareNotificationEnabled=true`; `IsClassChangingNotificationEnabled=true`; `IsClassOffNotificationEnabled=true`
|
||||
- `NotificationSoundVolume=1.0`; `IsNotificationEffectEnabled=true`; `IsNotificationSoundEnabled=true`; `IsNotificationTopmostEnabled=true`; `IsSpeechEnabled=true`; `SpeechVolume=1.0`
|
||||
- `IsAutoBackupEnabled=true`; `AutoBackupIntervalDays=7`; `AutoBackupLimit=16`
|
||||
- `AnimationLevel=1`; `IsAutomationEnabled=false`
|
||||
- `TaskBarIconClickBehavior`:Windows 0(打开主菜单),其他平台 4(打开设置窗口)
|
||||
|
||||
## 状态与枚举(待各 part 细化)
|
||||
- `TimeState`:OnClass / Breaking / ...(LessonsService.CurrentState)
|
||||
- TimeLayoutItem 类型:上课/课间/分割线/行动
|
||||
- NotificationPriority:见 Shared/Models/Notification
|
||||
- 隐藏模式 `HideMode`:0 基本(上课/最大窗口/全屏)、1 高级(规则集)
|
||||
|
||||
## ClassHelper 技术栈(固定)
|
||||
- pnpm 11.8.0;Node >= 20.19;Electron ^44.3.0;Vue ^3.5.42;Element Plus ^2.14.5;Pinia ^4.0.3;Vue Router ^5.3.1;Vite ^8.3.0;TypeScript ~5.9.3
|
||||
- 岛:独立 `island.html` + 独立 BrowserWindow;`squircle.ts`(p=2/4.2,14 段/角);`spring.ts`(stiffness 0.10,damping 0.68,snap 0.05px,动量保留 0.35,最大距离比 0.2,最大 dt 6 帧);`classic-island.css` 字号全部由 `--island-font` calc 推导;`tokens.css` 基础:`--ch-ui-primary:#5d6bfa`、radius 8px、gap 16px 等
|
||||
- 安全:preload contextBridge 白名单;CSP;不暴露 ipcRenderer;渲染层不持文件能力
|
||||
|
||||
## 已确认的动画片段(供 part 14 交叉核对)
|
||||
- 背景色 BrushTransition 200ms(MainWindow.axaml:40-44)
|
||||
- WrapPanel 尺寸动画 300ms cubic-bezier(0.65,0,0.35,1.0)(MainWindow.axaml:197-198)
|
||||
- Fluent 行背景 BoxShadowsTransition 100ms;进度条 Value 过渡 50ms Linear(FluentTheme/Styles.axaml:97,139-142)
|
||||
- Fluent 遮罩/背景:Opacity 100ms、BackgroundWidth 300ms;出现位移动画 250ms cubic-bezier(0.25,1,0.5,1)、延迟 260ms;尺寸动画 750ms 同曲线;延迟 600ms/100ms(FluentTheme/Styles.axaml:331-357,378-403)
|
||||
- Classic 主题:Opacity 100ms、BackgroundWidth 550ms cubic-bezier(0,1,0.5,1.1);动画 200ms 等(ClassicTheme/Styles.axaml:206-207,268-321)
|
||||
- 页面切换:PageSlide 300ms cubic-bezier(0.76,0,0.24,1) + CrossFade 300ms(ClassChangingWindow/DataTransferPage/WelcomePages)
|
||||
- OOBE 开场:3000ms cubic-bezier(0.00,0.83,0.17,0.90);后续 250ms cubic-bezier(0.76,0,0.24,1)、700ms cubic-bezier(0.33,1,0.68,1)(Controls/OobeIntroAnimationControl.axaml:16,47-48,93-105)
|
||||
- 教程聚光灯:750ms cubic-bezier(0.16,1,0.3,1);高亮环 1750ms(Controls/Tutorial/*.axaml)
|
||||
- 关于页 Logo:延迟 250ms、持续 200ms、Easing 0,0 0,1(AboutSettingsPage.axaml:136-137)
|
||||
|
||||
## 待核对项(Lead 会在汇总时检索)
|
||||
- 通知气泡的精确尺寸/圆角/间距(ClassNotificationProviderControl.axaml)
|
||||
- 强提醒特效的参数(TopmostEffectWindow + NotificationHostService)
|
||||
- 天气组件布局尺寸(WeatherComponent.axaml)
|
||||
- 课程表组件列宽/行高(ScheduleComponent.axaml)
|
||||
- OOBE 各页尺寸(WelcomeWindow.axaml)
|
||||
- 设置窗口尺寸(SettingsWindowNew.axaml)
|
||||
@@ -0,0 +1,69 @@
|
||||
# Round 2 总简报:重构 ClassHelper 灵动岛 → 给 ChatGPT 的完整提示词
|
||||
|
||||
## 0. 目标变化(以本轮用户要求为准)
|
||||
|
||||
用户的新要求:**基于 ClassIsland 项目反推出完整提示词,用它来重构 ClassHelper 的灵动岛**。
|
||||
即:不是从零新建一个 ClassIsland 克隆,而是让 ChatGPT 在 **ClassHelper 现有仓库**(pnpm monorepo,`packages/desktop-client` 等)里,参照 ClassIsland 的灵动岛(主界面)实现,把 ClassHelper 的灵动岛重构到位;技术栈、工程约定、既有数据与服务全部沿用 ClassHelper。
|
||||
|
||||
最终交付:`D:\clword\ClassHelper灵动岛重构-给ChatGPT的完整提示词.md`(简体中文,给 ChatGPT 的实现任务书,可直接投喂)。
|
||||
|
||||
## 1. 关键事实(已核对,必须遵守)
|
||||
|
||||
### 1.1 ClassHelper 灵动岛现状(详见 `docs/app/island.md` 与源码)
|
||||
- 独立透明窗口、不占任务栏;`config.json.islandLayout.layout` 为 `fixed`(经典)或 `custom`(自定义常驻),默认 `fixed`;两种布局共用一个原生窗口(`src/main/island.ts`)。
|
||||
- 经典 fixed:胶囊 + 详情卡,消息分普通/紧急、上课时普通通知暂存、普通叫人可点、紧急立即展开;支持细缝、触摸、失焦宽限、鼠标穿透/避让淡化。
|
||||
- 自定义 custom:多行 rows + expandedRows(无消息展开内容)、组件方案 schemes(多方案、JSON 导入导出)、组件树 nodes(`shared/src/island-layout.ts` 的 `IslandComponentNode`:id/kind/settings/appearance/advanced/children);行有 main / allowNotifications / gap;组件有 hideRules(in-class/no-message/no-class)、align、width、maxWidth;方案级 scale/color/foreground/opacity/radius/separated/spacing。
|
||||
- 组件种类:`ISLAND_COMPONENTS = date, clock, weather, countdown, schedule, text, separator, slide, rolling, group, stack, notification, homework, call`。`notification/homework/call` 为消息入口组件;组件库只展示前 11 类(消息类走铃铛/面板)。
|
||||
- 渲染入口:`island.html` → `LayoutIslandApp.vue`(选择经典 `IslandApp.vue` 或自定义 `CustomIslandRuntime.vue`),共用 `src/island/ComponentNode.vue`、`ComponentIcon.vue`、`ClassicNotifications.vue`、`LessonReminderContent.vue`、`CoursewareTransfer.vue`、`spring.ts`、`squircle.ts`、`classic-island.css`、`custom-island.css`、`custom-runtime.css`。
|
||||
- 主进程状态:`src/main/island.ts`(窗口几何/命中/触摸/消息队列/课程提醒/天气/课件);preload:`src/preload/island.ts`;渲染→主进程 IPC 走 contextBridge 白名单。
|
||||
- 课表数据来自服务端解析结果(`ScheduleDto`、`IslandTimePointDto` 等),天气用 Open-Meteo(15 分钟刷新、断网缓存标"缓存"),课程提醒含准备/上课/课间/下课前倒数/课中进度,下课前秒数徽标显示在课程名右侧(蓝色圆形,剩余一秒显示 `-1`)。
|
||||
- 课件传输状态优先覆盖岛内容(`CoursewareTransfer.vue`)。
|
||||
- 既有硬约束(`AGENTS.md` §4):保留经典岛连续圆角、投影常驻、触摸输入、失焦宽限、固定窗口几何护栏;**禁止** `setBackgroundMaterial()` 破坏逐像素透明;消息按 id 去重;通知/叫人双播不得重复;编辑预览不创建额外桌面窗口;默认后台验证不创建可见岛或托盘,只有显式 `--visual` 才做桌面像素/动画验收。
|
||||
|
||||
### 1.2 ClassIsland 灵动岛基准(上一轮已整理,可直接复用 `parts/03,04,05,07,14`)
|
||||
- 无边框/透明/不抢焦点/默认鼠标穿透;行高 40;行内容 `margin 0 12`、`min-width 20`;行间距默认 5;圆角 RadiusX 默认 8(0–20);背景不透明度 0.5、行整体不透明度 1.0;背景 1px 描边 + `0 4 8 2 #48000000`;字号 14/16/18/20;进度条 3px;选择框 1.5px 虚线 1/1.5;Fluent/Classic 两套主题;遮罩斜切 5 区权重 `[0,0.1,0.2,0.4,0.2,0.1]`、区段 360ms + 错峰 120ms、开 QuarticEaseOut / 关 QuadraticEaseIn、文字 delay 260/250ms + scale 1.1→1.0/750ms、退出 200ms `(0.5,0,0.75,0)`;行宽过渡 Fluent 300ms `(0.65,0,0.35,1)` / Classic 550ms `(0,1,0.5,1.1)`;通知队列优先级、强提醒全屏特效、音效/TTS;组件系统 11 类 + 容器;编辑模式(选择框/拖动/行设置抽屉/添加行/组件库);隐藏规则;多显示器停靠;壁纸取色已停用(P2)。
|
||||
- 完整细节在 `parts/`(上一轮产出):03 tokens、04 主界面、05 组件、07 提醒、14 动画(99 条)、10 设置、11 窗口。可裁剪/改写后复用。
|
||||
|
||||
## 2. 本轮重构决策(Lead 定,所有 part 必须一致)
|
||||
|
||||
1. **在现有仓库内重构,不新建工程、不引入新框架**:pnpm@11.8.0 monorepo;Electron ^44.3.0、Vue ^3.5.42、Element Plus ^2.14.5、Pinia ^4.0.3、Vue Router ^5.3.1、Vite ^8.3.0、TS ~5.9.3 原样沿用;不引入 ClassIsland 的 C#/Avalonia、不引入服务端新依赖。
|
||||
2. **目标视觉默认改为 ClassIsland 规格**:岛可见行高 40、行内边距 12、行间距 5、圆角 8、背景不透明度 0.5、字号 14/16/18/20、进度条 3px、通知气泡/强提醒按 ClassIsland 参数。**保留 ClassHelper 经典 WinIsland 外观作为可选风格**(`islandAppearance.style: 'classisland' | 'winisland'`,默认 `classisland`;经典胶囊交互在 `winisland` 下不变),用于老用户与回退。
|
||||
3. **两种模式的定位**(最终以 parts-r/01 为准):
|
||||
- `fixed`(默认风格 `classisland`):**重定义为 ClassIsland 风格的信息行**——默认 1 行 = 日期 + 课程表,行高 40、圆角 8、背景不透明度 0.5、底部 3px 进度条;消息到来时在同一行内展开 ClassIsland 风格气泡,保留 ClassHelper 的暂存/紧急/叫人/已读规则。原「胶囊 + 详情卡」形态**只在 `winisland` 兼容风格下保留**(`appearance.family='winisland'`)。
|
||||
- `custom`(常驻):保留现有 schemes/rows/nodes/expandedRows/编辑器的数据模型,按 ClassIsland 的行/组件/编辑模式/隐藏规则/动画规格重构渲染与交互;行高 40、组件间距、行设置抽屉、组件库拖拽、主行/允许提醒/淡出规则与 ClassIsland 对齐。
|
||||
4. **数据来源不迁移到 ClassIsland 本地档案**:继续使用 ClassHelper 服务端解析后的 `ScheduleDto`/`IslandTimePointDto`/通知/作业/叫人/课件数据;ClassIsland 的 Profile/TimeLayout 只作为"语义参考",不引入其本地 JSON 档案体系。
|
||||
5. **消息/提醒**:保留 ClassHelper 的优先级、去重、上课暂存、紧急展开、已读回执、安静模式等业务规则;在此基础上叠加 ClassIsland 的气泡两阶段、强提醒特效(Topmost)、倒计时进度条、行内进度条等视觉/交互;两者冲突时以"ClassHelper 业务语义优先,ClassIsland 视觉表现优先"为裁决。
|
||||
6. **ClassIsland 的自动化/插件/主题市场/管理端/Excel 导入/更新器不在本轮范围**(最多作为附录说明不实现);主题只做岛内样式(CSS 变量 + 两套内置风格)。
|
||||
7. **配置兼容**:`config.json.islandLayout` 增加 `version` 字段与迁移函数;旧 `fixed`/`custom` 配置必须无损升级(组件节点、方案、外观值、编辑器行为保持),失败可回滚;旧字段 `residentEnabled` 继续兼容。
|
||||
8. **不打扰纪律**:所有验证必须无头/离屏(`verify:desktop` 默认后台快速检查,不创建可见岛/托盘;只有显式 `--visual` 才做视觉验证),禁止自动弹窗、发声、占用真实桌面。
|
||||
|
||||
## 3. 文档结构(最终提示词)
|
||||
|
||||
| Part | 内容 | 负责人 | 文件 |
|
||||
|---|---|---|---|
|
||||
| 0 | 使用说明 + 给 ChatGPT 的任务声明(重构、约束、交付、工作方式) | Lead | parts-r/00-preamble.md |
|
||||
| 1 | 重构目标与范围(背景、目标态、Keep/Change/Add、非目标) | Lead | parts-r/01-objective.md |
|
||||
| 2 | ClassHelper 灵动岛现状基线(文件、进程、数据、交互、既有规则) | stack | parts-r/02-current-state.md |
|
||||
| 3 | ClassIsland 灵动岛基准规格(行为语义:行/组件/提醒/课程/隐藏/课程表/天气) | features | parts-r/03-classisland-baseline.md |
|
||||
| 4 | 目标架构与文件级改造清单(模块划分、文件、接口、IPC、改动类型) | stack | parts-r/04-file-plan.md |
|
||||
| 5 | 数据契约、schema 扩展与配置迁移(islandLayout v2、DTO 映射、迁移/回滚) | stack | parts-r/05-data-migration.md |
|
||||
| 6 | 设计 tokens 与视觉基线(颜色/字体/圆角/间距/阴影/层级/DPI;两套风格) | design | parts-r/06-tokens.md |
|
||||
| 7 | 岛结构与组件规格(窗口/几何/行/背景/进度/遮罩/编辑模式/11+ 组件逐个) | ui-island | parts-r/07-island-components.md |
|
||||
| 8 | 消息、提醒、课程提醒、强提醒特效、天气、课件覆盖(含像素与动画) | features | parts-r/08-messages-lessons.md |
|
||||
| 9 | 编辑器与设置页重构(IslandSettingsView / IslandEditorView / IslandComponentSettings / 设置页) | windows | parts-r/09-editor-settings.md |
|
||||
| 10 | 动画与动效映射(ClassHelper 现状 → 目标;逐项 ms/曲线/延迟/实现;含降级) | design | parts-r/10-animations.md |
|
||||
| 11 | 兼容性、性能、平台与测试基线(迁移回滚、无头验证、性能预算) | Lead | parts-r/11-compat-tests.md |
|
||||
| 12 | 验收清单(逐项可勾选) | Lead | parts-r/12-acceptance.md |
|
||||
| 13 | 重构里程碑(M0–M7) | Lead | parts-r/13-milestones.md |
|
||||
|
||||
## 4. 写作规范(与上一轮一致)
|
||||
- 简体中文、祈使句、面向 ChatGPT;不是分析报告。
|
||||
- 证据:`packages/...:行号`(ClassHelper 仓库相对路径);ClassIsland 侧写 `repos/ClassIsland/...:行号`(相对本工作区),无法确认标【推断】。
|
||||
- 必须写清「改哪个文件、改成什么样、为什么、如何验证」;每个 part 末尾含「验收标准」。
|
||||
- 不建新工程、不改服务端、不引入新框架;坚持"重构"措辞。
|
||||
- **禁止构建/运行/截图/冒烟/启动 Electron**,只读分析。用户明确要求后台静默,不要打扰。
|
||||
- 不要修改 `repos/`;只写 `parts-r/`、`analysis/`、最终由 Lead 汇总。
|
||||
|
||||
## 5. 待读清单(关键)
|
||||
ClassHelper:`docs/app/island.md`、`docs/dev/implementation.md`、`docs/dev/winisland-design-tokens.md`、`packages/shared/src/{island-layout,constants,motion}.ts`、`packages/desktop-client/src/main/island.ts`、`src/island/{LayoutIslandApp,IslandApp,CustomIslandRuntime,ComponentNode,ComponentIcon,ClassicNotifications,LessonReminderContent,CoursewareTransfer,spring,squircle}.ts/vue`、`src/island/{classic-island,custom-island,custom-runtime,lesson-ending}.css`、`src/preload/island.ts`、`src/renderer/island/bridge.ts`、`src/renderer/views/settings/{IslandSettingsView,IslandEditorView}.vue`、`src/renderer/components/IslandComponentSettings.vue`、`src/main/config.ts`、`src/types/desktop.d.ts`。
|
||||
ClassIsland:上一轮 `parts/03,04,05,07,10,11,14` 与 `analysis/40-baseline.md` 已整理,可直接引用;必要时回查 `repos/ClassIsland` 源码。
|
||||
@@ -0,0 +1,176 @@
|
||||
# ClassHelper 技术栈调研笔记(Part 02/12/13 支撑)
|
||||
|
||||
> 本文件是队友 `stack` 的静态分析记录,供 Lead 汇总审校时核对"我读了什么、为什么这样映射、还剩什么不确定"。
|
||||
> 全程只使用 read/grep/glob 与纯文本统计命令;**未执行任何构建、安装、运行、截图、冒烟或 UI 命令**;未修改 `repos/` 下任何文件。
|
||||
|
||||
## 1. 已读文件清单
|
||||
|
||||
### 1.1 ClassHelper(`repos/ClassHelper-master`)
|
||||
|
||||
| 文件 | 用途 |
|
||||
|---|---|
|
||||
| `package.json` | 根版本单一来源、`pnpm@11.8.0`、Node `>=20.19.0`、全部脚本(build/dev/typecheck/lint/dist/version) |
|
||||
| `pnpm-workspace.yaml` | workspace 定义、`allowBuilds` 白名单、`verifyDepsBeforeRun` |
|
||||
| `tsconfig.base.json` | 目标 ES2023、NodeNext、strict、verbatimModuleSyntax、declaration |
|
||||
| `packages/desktop-client/package.json` | Electron 44.3、Vue 3.5.42、Element Plus 2.14.5、Pinia 4.0.3、Vue Router 5.3.1、Vite 8.3、TS 5.9.3、electron-builder 26.15.3、esbuild 0.28.2 |
|
||||
| `packages/desktop-client/electron-builder.yml` | appId/productName、`electronLanguages: [zh-CN]`、files/asar/npmRebuild、win nsis+portable、artifactName |
|
||||
| `packages/desktop-client/vite.config.mts` | 双入口(index/island)、`base:'./'`、outDir `dist/renderer`、5174 strictPort |
|
||||
| `packages/desktop-client/island.html` / `index.html` | 透明底、CSP 全指令、preload 挂载点 |
|
||||
| `packages/desktop-client/scripts/build-main.mjs` | esbuild CJS 主进程/preload/岛 preload、产物路径、更新助手编译 |
|
||||
| `packages/desktop-client/scripts/dev.mjs` | Vite 就绪探测 → Electron 启动、`VITE_DEV_SERVER_URL` |
|
||||
| `packages/desktop-client/src/main/index.ts` | 单实例、启动时序、设置窗口参数、导航白名单、开机自启、托盘、退出清理 |
|
||||
| `src/main/config.ts` | `config.json` 路径、`PersistedConfig` 全字段与默认值、归一化、safeStorage、120ms 合并写、`flushConfigSync`、`deviceKey` |
|
||||
| `src/main/island.ts`(前 1140 行) | 岛窗口全参数、固定包围盒、命中/穿透、失焦宽限、触摸模式、`CLOSE_ANIMATION_MS=360`、各状态超时表、通知队列与动作 |
|
||||
| `src/main/ipc.ts` | IPC handler 注册、配置白名单剔除、appInfo、自启、日志目录、DevTools、client status |
|
||||
| `src/main/channels.ts` | 通道名叶子模块(零 import)与原因 |
|
||||
| `src/main/tray.ts` | 托盘菜单与图标兜底 |
|
||||
| `src/main/logger.ts` | `main.log`、1MB 轮转、懒解析、格式与堆栈写入 |
|
||||
| `src/main/crash-guard.ts` | 崩溃自愈三条路径、10 分钟 3 次限流、空闲重启、冒烟豁免 |
|
||||
| `src/main/auto-update.ts` | 更新策略、文件名校验、下载/校验/差分、空闲 5 分钟、安装助手、结果文件 |
|
||||
| `src/main/island.ts`(1141+ 行片段经 grep) | `recoverWindow`、命中轮询、`alive` 心跳相关字段 |
|
||||
| `src/preload/index.ts` | `window.desktop` 全量白名单、订阅可取消、纯数据约束 |
|
||||
| `src/preload/island.ts` | `window.island` 全量白名单(状态/外观/尺寸/命中/触摸/心跳) |
|
||||
| `src/types/desktop.d.ts` | 桥接契约、`DesktopStoredConfig` 全字段、`IslandState`、冒烟钩子 |
|
||||
| `src/island/main.ts` | 岛入口零 UI 库、二次注入动效令牌 |
|
||||
| `src/island/spring.ts` | WinIsland 弹簧参数、换向限速、零过冲钳制 |
|
||||
| `src/island/squircle.ts` | 连续圆角(p=4.2、14 段/角)、展开半径 |
|
||||
| `src/renderer/composables/motion.ts` | 令牌注入、reduced-motion、hover 能力、count-up、stagger、主题揭示 |
|
||||
| `src/renderer/main.ts` | 应用窗口挂载顺序、冒烟动态 import |
|
||||
| `src/renderer/router/index.ts` | hash 路由、守卫、路由表结构 |
|
||||
| `src/renderer/cache/db.ts` | IndexedDB 缓存层(`classhelper-cache`、object store 列表、容错) |
|
||||
| `packages/shared/package.json` / `src/index.ts` / `src/motion.ts` / `src/island-layout.ts` / `src/constants.ts`(255-364 行)/ `src/types.ts`(ScheduleDto、IslandNotification、IslandState 片段) | 共享类型、动效令牌、岛方案 schema 与 normalize、外观默认值/范围、尺寸增量、ClassIsland 度量常量 |
|
||||
| `packages/ui/package.json` / `src/tokens.css` / `src/index.ts` 文件清单 | 共享 UI 消费方式、基础令牌与深色覆盖 |
|
||||
| `docs/dev/architecture.md` | 目录职责、数据流、更新助手链路、工程边界 |
|
||||
| `docs/dev/motion.md` | 动效令牌表、CSS linear() 弹簧、四条硬约束、主题两条纪律 |
|
||||
| `docs/dev/winisland-design-tokens.md` | 经典岛几何、自定义行度量、禁用 `setBackgroundMaterial`、阴影常驻 |
|
||||
| `docs/dev/release.md` | 版本单一来源、构建与验证顺序、产物命名 |
|
||||
| `docs/get-started/requirements.md` | 客户端内存/磁盘/触摸屏/平台要求(250–350MB、仅 Windows) |
|
||||
| `AGENTS.md`(自动注入) | preload 白名单、CSP、离线缓存隔离、岛方案字段、验证纪律、发布纪律 |
|
||||
|
||||
### 1.2 ClassIsland(`repos/ClassIsland`)
|
||||
|
||||
| 文件 | 用途 |
|
||||
|---|---|
|
||||
| `ClassIsland/Program.cs` | 命令行参数全集、`Global\ClassIsland.Lock` 单实例、URI 二次启动转发、Sentry、进程优先级 |
|
||||
| `ClassIsland.Launcher/Program.cs` | 多版本目录枚举(`app*`、`.current`、`.destroy`、`.partial`)、Linux 执行权限 |
|
||||
| `ClassIsland/Services/SettingsService.cs` | `Settings.json` 加载/保存、版本迁移门、设置叠层(Add/RemoveSettingsOverlay)、属性变更即保存 |
|
||||
| `ClassIsland/Models/Settings.cs` | 211 个默认值字段(grep `private .* _\w+ = ` 全量提取) |
|
||||
| `ClassIsland.Shared/Helpers/ConfigureFileHelper.cs` | `.bak` 备份/回退、原子写、`MergeDictionary`、`CopyObject`、反序列化选项 |
|
||||
| `ClassIsland.Shared/Models/ConfigError.cs` | 配置错误记录模型(只读声明) |
|
||||
| `ClassIsland/Services/ProfileService.cs` | 档案路径、管理端拉取、临时层清理、信任档案、切换保存 |
|
||||
| `ClassIsland.Shared/Models/Profile/Profile.cs` | 档案根字段、默认群、编辑科目、临时层、预定课表 |
|
||||
| `.../Profile/TimeLayout.cs` / `TimeLayoutItem.cs` / `ClassPlan.cs` / `ClassInfo.cs` / `TimeRule.cs` / `Subject.cs` / `ClassPlanGroup.cs` / `OrderedSchedule.cs` | 课表数据模型全字段、默认值、`[JsonIgnore]`、GUID 空回退、有效时间点算法 |
|
||||
| `ClassIsland/Services/ComponentsService.cs` | 组件布局路径/默认布局 GUID/迁移/保存时机 |
|
||||
| `ClassIsland.Core/Models/Components/{ComponentProfile,MainWindowLineSettings,ComponentSettings,ComponentGroup}.cs` | 组件布局全字段与默认值 |
|
||||
| `ClassIsland/Models/ComponentSettings/*.cs`(9 个) | 组件专属设置模型清单 |
|
||||
| `ClassIsland/Services/AutomationService.cs` | 自动化目录、`Workflow[]` 顶层、切换保存、信任档案门槛、时间点行动、触发/恢复语义 |
|
||||
| `ClassIsland.Core/Models/Automation/{Workflow,TriggerSettings,ActionMenuTreeNode}.cs`、`ClassIsland.Shared/Models/Automation/{ActionSet,ActionItem}.cs` | 自动化数据结构与 `Actions` 序列化名 |
|
||||
| `ClassIsland.Core/Models/Ruleset/{Ruleset,Rule,RuleGroup,StringMatchingSettings}.cs` | 规则集结构与默认值(Or/And、IsReversed、IsEnabled) |
|
||||
| `ClassIsland/Services/Automation/{Triggers,Actions}/*.cs`(grep `TriggerInfo`/`ActionInfo`) | 12 个触发器 ID、7 个动作 ID |
|
||||
| `ClassIsland/Services/PluginService.cs` | `.cipx` 安装/解压/`.disabled`/`.uninstall`、清单解析、API 版本门槛、依赖拓扑、插件配置目录、审计 |
|
||||
| `ClassIsland.Core/Abstractions/PluginBase.cs` / `Services/IPluginService.cs` / `Models/Plugin/{PluginManifest,PluginInfo,PluginIndex,PluginIndexItem,PluginDependency,PluginRepoManifest}.cs` / `Enums/PluginLoadStatus.cs` | 插件模型、市场索引、加载状态 |
|
||||
| `ClassIsland/Services/PluginMarketService.cs` | 回退镜像、索引刷新 7 天、默认索引 URL |
|
||||
| `ClassIsland.PluginSdk/ClassIsland.PluginSdk.targets` / `generate-md5.ps1` | 插件打包成 `.cipx`、`checksums.md` 的 MD5 注释 |
|
||||
| `ClassIsland/Services/IpcService.cs`、`ClassIsland.Shared.IPC/{IpcClient,IpcRoutedNotifyIds}.cs`、`Abstractions/Services/IPublic*.cs`、`README.md` | 命名管道 IPC、公开服务契约、事件通知 ID |
|
||||
| `ClassIsland.Core/CommonDirectories.cs` / `Services/GlobalStorageService.cs` | 路径划分、机器级全局存储 |
|
||||
| `ClassIsland/Services/FileFolderService.cs` | 需创建目录全集、备份内容与命名、自动备份策略 |
|
||||
| `ClassIsland/Services/XamlThemeService.cs`(grep) | 主题路径、`EnabledThemes.json`、主题包缓存 |
|
||||
| `ClassIsland/Services/AppUpdating/UpdateService.cs`(1-150、380-500、630-880 行) | 更新通道/状态枚举、部署锁、文件图签名、差分、`.partial/.current/.destroy`、压缩包校验 |
|
||||
| `ClassIsland/Models/AppUpdating/DeploymentLock.cs`、`Models/{UpdateChannel,UpdateSource}.cs`、`ClassIsland.Shared/Enums/{UpdateStatus,UpdateWorkingStatus}.cs` | 更新模型与状态 |
|
||||
| `ClassIsland.Shared/Models/Notification/{NotificationSettings,NotificationPriority,NotificationRequest}.cs`、`ClassIsland.Core/Models/Notification/NotificationRequest.cs` | 提醒设置/优先级/播放会话字段 |
|
||||
| `ClassIsland.Core/Converters/ColorHexJsonConverter.cs`、`ClassIsland.Shared/JsonConverters/GuidEmptyFallbackConverter.cs` | 颜色与空 GUID 的 JSON 兼容规则 |
|
||||
| `ClassIsland.Core/Models/XamlTheme/ThemeManifest.cs` | 主题清单字段与默认值 |
|
||||
| `examples/example.json` | 真实档案 JSON 形态(PascalCase、StartSecond 旧字段、`AttachedObjects`、TimeType 注释) |
|
||||
| `AGENTS.md`(自动注入) | 仓库形状、SDK 版本、构建与验证纪律、Avalonia 开发规则 |
|
||||
|
||||
### 1.3 团队上下文
|
||||
|
||||
- `analysis/00-brief.md`(总简报、纪律、术语、分工)
|
||||
- `analysis/40-baseline.md`(Lead 核对的 canonical 数值)
|
||||
- `parts/01-overview.md`(总纲:三进程模型、ClassHelper 栈、P0/P1/P2 模块)
|
||||
- 共享任务 `task-1`(认领/完成状态)
|
||||
|
||||
## 2. ClassIsland → ClassHelper 映射决策(含理由)
|
||||
|
||||
### 2.1 已定决策(写入 parts)
|
||||
|
||||
| 决策 | 选择 | 理由 / 证据 |
|
||||
|---|---|---|
|
||||
| 工程形态 | pnpm monorepo:`shared` + `ui` + `desktop-client` | 复用 ClassHelper 已验证结构(`pnpm-workspace.yaml:1-2`、`desktop-client/package.json`) |
|
||||
| 包管理/运行时 | pnpm 11.8.0、Node ≥20.19 | 根 `package.json:6-9`;`allowBuilds` 必须显式声明,否则 install 失败 |
|
||||
| 桌面壳 | Electron 44.3 + electron-builder 26.15 | 唯一被团队指定且与 ClassHelper 对齐 |
|
||||
| 进程模型 | 主进程 / 应用窗口渲染 / 岛渲染 / 插件 utilityProcess / 更新助手 | 保留 ClassHelper 三进程 + 新增隔离进程(ClassIsland 的插件 `PluginLoadContext` 在 Electron 下的等价物是进程隔离) |
|
||||
| 数据形态 | 本地 JSON 文件(ClassIsland 兼容 PascalCase 档案 + camelCase 运行配置) | ClassIsland 是单机应用;ClassHelper 的 IndexedDB 缓存是"服务端离线缓存",本应用无服务端,故只保留 JSON 文件 + 可选内存缓存 |
|
||||
| 数据根目录 | `app.getPath('userData')` | Electron 正确做法;ClassIsland 的 `AppRootFolderPath` 在便携/安装两种形态下语义不同,用 userData 统一 |
|
||||
| 主界面窗口 | 岛窗口 = ClassIsland MainWindow;设置窗口 = 新增 | 团队总纲第 1.6 节要求三进程分离;岛必须透明置顶,设置窗口是普通窗口 |
|
||||
| 岛形变 | `SpringValue` 帧积分 + squircle 连续圆角 | ClassHelper 已验证(`spring.ts`、`squircle.ts`),且 ClassIsland 的 `WrapPanel` 尺寸动画可平滑映射 |
|
||||
| 主题 | CSS 变量 + `html.dark` + 主题包目录 | ClassIsland 是 XAML 资源字典;Vue 下唯一可行且可热切换的等价物 |
|
||||
| 插件包 | `.cipx` = zip + `manifest.yml`(camelCase)+ ESM 入口 | 保留 ClassIsland 生态语义(清单字段/依赖/API 版本/`.disabled`/`.uninstall`),把 DLL 入口换成 `main.mjs` |
|
||||
| 插件市场 | 多源索引 JSON + 镜像回退 + MD5(兼容)+ SHA-256(安全) | 对齐 `PluginIndex`/`PluginMarketService`,并补足 ClassIsland 只校验 MD5 的弱点 |
|
||||
| 更新 | 自研:清单 + SHA-256 + 独立安装助手 + 三档安装时机 | ClassIsland 是 `FileMap` 分组件部署 + Launcher 多版本;Electron 下以 NSIS 安装目录 + 助手替换 + 回滚副本等价实现(标注【推断】) |
|
||||
| 单实例 | `requestSingleInstanceLock` + `second-instance` | 对齐 ClassIsland `Mutex` 语义,且 Electron 原生支持 |
|
||||
| 外部进程集成 | 默认关闭本地 HTTP;插件通过宿主 API | ClassIsland 有命名管道 IPC 公开服务;Electron 不暴露等价物,改为按需可选的 localhost HTTP |
|
||||
| 崩溃自愈 | 崩溃重建 + 无响应 10s 重建 + 内存 1.5GB 看门狗 + 10 分钟 3 次限流 | 直接对齐 `crash-guard.ts` 与 `MemoryWatchDogService.cs` |
|
||||
| 日志 | 自研 `logger.ts`(main.log + 1MB 轮转) | 与 ClassHelper 完全一致;不引入 electron-log 以减少不可控行为 |
|
||||
| 自动备份 | `backups/Auto_*.zip`,7 天/16 份 | 对齐 `FileFolderService.cs:83-113` |
|
||||
| 安全 | CSP + contextBridge 白名单 + sandbox + 导航白名单 + 凭据门禁 + 插件权限 | 与 ClassHelper AGENTS.md 完全一致;插件权限是在 ClassIsland(全信任 DLL)之上的主动增强【推断】 |
|
||||
|
||||
### 2.2 有意偏离 ClassIsland 的地方(必须在提示词中说明)
|
||||
|
||||
1. **插件权限模型**:ClassIsland 插件是进程内 DLL,天然全信任;本实现必须默认拒绝、按 `permissions` 放行。属安全增强,不是功能缺失。
|
||||
2. **热更新/热重载**:ClassIsland 有 HotAvalonia(开发期);本实现只在开发期用 Vite HMR,生产不得热替换插件。
|
||||
3. **管理端(集控)**:ClassIsland 有 `ManagementService`(管理服务器下发设置/档案);本任务明确不要求后端,P2 可选。提示词中应写"默认不实现,预留接口"。
|
||||
4. **Sentry**:ClassIsland 默认开启匿名崩溃上报;本实现默认提示可关闭,且不得上报课表/个人信息。
|
||||
5. **多平台**:ClassIsland 支持 Windows/Linux/macOS;本实现主目标 Windows(触摸屏/希沃),macOS/Linux 尽力支持但不得阻塞 Windows 验收。
|
||||
|
||||
### 2.3 与其他 part 的边界
|
||||
|
||||
- Part 03(设计 tokens):`tokens.css` 数值我引用了基础令牌,但**完整色板/字号阶梯归 Part 03**;我未在 02 中重定义。
|
||||
- Part 04/05(主界面/组件):岛窗口参数、组件行度量、组件布局 schema 的"存储字段"归我(13.5),"视觉与交互"归 04/05,已在 13.5 注明"视觉见第 5 部分"。
|
||||
- Part 06/07/08(课表/提醒/自动化):数据 schema 我给出字段级清单,业务语义(触发时机、队列行为)归 06/07/08;我在 13.4/13.6/13.7 只规定"存什么、默认值、兼容规则"。
|
||||
- Part 09(主题):主题目录与 `EnabledThemes.json`、`ThemeManifest` 字段归我(13.8),CSS 变量清单与壁纸取色算法归 09。
|
||||
- Part 10/11(设置/其他窗口):设置页字段默认值我给了 13.3 全表,页面分组与控件归 10。
|
||||
- Part 14(动画总表):我只引用 spring/squircle/动效令牌的数值,未展开逐动画时间表。
|
||||
- Part 16/18(验收/禁止):我给出的验收标准是"本部分自查",与总验收不冲突。
|
||||
|
||||
## 3. 未决问题 / 缺口(交给 Lead 决策或后续 part 补齐)
|
||||
|
||||
1. **更新安装目录策略**:ClassIsland 用 Launcher 枚举 `app-<版本>` 目录实现"多版本 + 回滚";Electron + NSIS 下我建议"固定安装目录 + 助手替换 + 回滚副本",但**是否允许 side-by-side 多版本目录**需要 Lead 确认(影响 02/12 的更新章节与 17 里程碑)。
|
||||
2. **插件清单字段名**:ClassIsland 的 `manifest.yml` 用 `camelCase`(YamlDotNet `CamelCaseNamingConvention`)。我按 camelCase 写;若团队希望与"PascalCase 档案"统一,需要在 Part 12 全局替换(会影响导入 ClassIsland 插件包)。
|
||||
3. **插件设置页渲染方式**:我规定"声明式 schema,不允许任意 HTML"(安全),但 ClassIsland 插件可提供任意 Avalonia 控件;若要求 1:1 还原插件 UI 能力,需要引入受限的 iframe/webview 方案(会带来安全与样式隔离成本)——建议按声明式实现并在 Part 12 注明"这是有意限制"。
|
||||
4. **外部进程 IPC**:ClassIsland 公开 `IPublicLessonsService`/`IPublicProfileService` 给外部程序(命名管道)。我建议默认关闭 localhost HTTP;若产品需要"第三方读取当前课程",需要 Lead 决定是否实现并规定端口/鉴权。
|
||||
5. **`AttachedObjects`(附加设置)兼容**:ClassIsland 1.7 档案在 `TimeLayoutItem` 下有 `AttachedObjects`(提醒/天气/附加信息附加设置)。我在 13.4.3 规定"导入保留、新代码不写",但 Part 06/07 如果要支持"每个时间点的课级提醒设置",需要把该字段升级为一等公民。
|
||||
6. **`Settings.json` 双写问题**:我规定 `config.json`(camelCase)为主、`Settings.json`(PascalCase)仅导入导出时出现;若团队希望"用户可以直接编辑 ClassIsland 风格的 Settings.json",需要改成以 PascalCase 为主(牵动 02/10/13)。
|
||||
7. **通知历史是否落盘**:ClassIsland 没有持久化通知历史;我按"通知中心"需求(Part 07/11)推断了 `notification-history.json` 与 500 条上限,需 Part 07 确认。
|
||||
8. **多显示器与 DPI**:`windowDockingMonitorIndex`、`followCursorDisplay`、`scale` 的 DPI 换算规则我未展开(属 Part 04);Part 04 需要给出"逻辑像素 vs 物理像素"的统一口径,避免 02 的窗口参数与 04 的定位算法冲突。
|
||||
9. **`isIslandSeperated` 拼写**:ClassIsland 源码确实是 `IsIslandSeperated`(少一个 a,`Settings.cs:1852`)。为导入兼容必须保留该拼写;Part 04/10 若写正确拼写会造成字段不匹配。
|
||||
10. **触摸模式与窗口形状**:`setShape` 只在 Windows 生效;macOS/Linux 需要不同的命中策略(ClassHelper 也没覆盖)。提示词中应写明"非 Windows 平台降级为整窗接收鼠标"。
|
||||
11. **更新签名**:ClassIsland 的更新清单有签名(`DetachedSignatureProcessor`);我要求"必须签名",但密钥管理(公钥内置、轮换策略)需要 Lead 在 Part 17/18 里给一句总纪律。
|
||||
12. **插件/主题市场的默认源**:我引用了 ClassIsland 的官方索引 URL 作为示例;本实现是否内置该源(涉及外网与合规)需要 Lead 决定,建议默认"仅用户手动添加源"。
|
||||
|
||||
### 3.1 最终裁决(Lead 已确定,已并入 parts 并覆盖上述 1–12 条)
|
||||
|
||||
1. 更新安装:固定安装目录 + 独立更新助手替换 + `updates/rollback/<旧版本>/` 回滚副本,**不做 side-by-side 多版本**。
|
||||
2. 插件清单:统一 camelCase 写出,**兼容读取** PascalCase 旧清单并归一化。
|
||||
3. 插件设置页:只能声明式 schema,禁止任意 HTML/iframe/DOM 访问(安全红线)。
|
||||
4. 外部读取课程:**可选**本地只读 HTTP API(仅 127.0.0.1、随机端口、默认关闭、一次性 token),不恢复命名管道。
|
||||
5. `AttachedObjects` 升级为一等公民 `attachedObjects`(Profile/ClassPlan/ClassInfo/TimeLayout/TimeLayoutItem/Subject),接收 `AttachedObjects` 原拼写。
|
||||
6. 数据文件:`config.json` 为主 + `Settings.json` 只读导入/导出兼容层(不双向双写),保留 `IsIslandSeperated`。
|
||||
7. 通知历史:默认 500 条、可调 100–5000、滚动删除、写入节流(≥5 条或 ≥5s)。
|
||||
8. 坐标:全部使用 DIP(CSS px),窗口 bounds 也按 DIP;仅截图验收用 `devicePixelRatio`。
|
||||
9. 非 Windows 无 `setShape`:降级为整窗 `setIgnoreMouseEvents(true,{forward:true})` + 岛可见区内命中。
|
||||
10. 更新清单:SHA-256 必校验 + 可选 Ed25519(`keyId`、公钥轮换);默认只接受 https,镜像需显式开启并提示风险。
|
||||
11. 插件/主题市场:默认不内置在线官方索引,仅离线示例索引;用户手动添加并二次确认后才联网。
|
||||
12. 其余按原写法。
|
||||
13. `AttachedObjects` 不是 1.7 遗留:`AttachableSettingsObject.cs:15` 定义、2.x `AttachedSettingsControlPresenter.axaml.cs:241,361` 仍读写;已补 4 个已知 Guid 与设置对象类型(课程显示/上课提醒/放学提醒/天气提醒)。
|
||||
14. 已补天气数据 schema 一节(`WeatherInfo`/`WeatherAlert`/`ForecastDaily`/`ForecastHourly`/`Minutely`/`AqiInfo`/`WeatherQueryResult` + 缓存/来源/刷新/预警清洗 + 5 个规则 ID),与 07 对齐。
|
||||
15. Excel 导入导出定为 **P1 必须实现(xlsx 重建)**,ReoGrid/WPF 仅参考;已写导入/导出/8MB 上限/导入前备份/worker 执行要求。
|
||||
|
||||
新增研读文件(为裁决 13/14/15):`ClassIsland.Shared/AttachableSettingsObject.cs`、`ClassIsland.Core/Controls/AttachedSettingsControlPresenter.axaml.cs`(241-253)、`ClassIsland.Core/Models/AttachedSettings/LessonControlAttachedSettings.cs`、`ClassIsland/Models/AttachedSettings/{ClassNotification,WeatherNotification,AfterSchoolNotification,Test}AttachedSettings.cs`、`ClassIsland/Controls/AttachedSettingsControls/*.axaml.cs`(Guid 与 Usage 目标)、`ClassIsland.Core/Enums/AttachedSettingsTargets.cs`、`ClassIsland.Core/Models/Weather/*.cs`(`WeatherInfo`/`WeatherAlert`/`CurrentWeather`/`ForecastDaily`/`ForecastHourly`/`Minutely`/`MinutelyPrecipitation`/`AqiInfo`/`ValueUnitPair`/`WindInfo`/`RangedValue`/`StatusValueBase`/`WeatherQueryResult`)、`ClassIsland/Services/WeatherService.cs`(来源/刷新/过滤)、`ClassIsland/Views/ExcelImportWindow.xaml.cs`、`ExcelExportWindow.xaml.cs`(ReoGrid 参考)、`Settings.cs:113,2122-2130`(`ExpIsExcelImportEnabled` 默认 false)。
|
||||
|
||||
## 4. 静态分析纪律声明
|
||||
|
||||
- 全程只读:`read` 读文本、`grep`/`glob` 找文件、`Select-String`/`Get-Content` 做纯文本统计、`[regex]` 统计中文字符数。
|
||||
- 未执行 `dotnet build/run`、`pnpm install/dev/build`、`electron`、`npm`、截图、冒烟或任何会弹窗/占用屏幕的命令。
|
||||
- 未修改 `repos/ClassIsland` 与 `repos/ClassHelper-master` 下任何文件;只写入了 `parts/02-tech-stack.md`、`parts/12-plugins-ipc.md`、`parts/13-data-storage.md`、`analysis/classhelper-stack.md`。
|
||||
- 证据标注口径:`repos/...:行号`;无法从源码直接确认的工程设计一律标【推断】。
|
||||
@@ -0,0 +1,143 @@
|
||||
# 设计组分析记录(design)
|
||||
|
||||
本文件记录 part 03 / 09 / 14 / 15 的源码依据、已读文件清单、token 对照表与未决问题。写作纪律:只读源码、未构建/未运行任何程序、未修改 `repos/` 下文件。
|
||||
|
||||
## 1. 已读文件清单
|
||||
|
||||
### 1.1 ClassIsland(应用层)
|
||||
|
||||
| 文件 | 读取范围 | 用途 |
|
||||
|---|---|---|
|
||||
| `ClassIsland/Themes/Generic.xaml` | 全文 467 行 | 资源字典、时间线模板、FocusVisual 描边、DropShadow 参数 |
|
||||
| `ClassIsland/Themes/LightTheme.axaml` | 全文 21 行 | 亮色覆盖:Rainy/AQI/CustomizedAccentBar/InformativeSecondary/LuminousClass |
|
||||
| `ClassIsland/Themes/DarkTheme.axaml` | 全文 21 行 | 深色覆盖 |
|
||||
| `ClassIsland/XamlThemes/FluentTheme/Styles.axaml` | 全文 457 行 | Fluent 主题行模板、遮罩动画、过渡、分体岛 |
|
||||
| `ClassIsland/XamlThemes/ClassicTheme/Styles.axaml` | 全文 375 行 | 经典主题行模板、下压/上滑遮罩、过冲曲线 |
|
||||
| `ClassIsland/App.axaml` | 全文 57 行 | FluentAvaloniaTheme、ThemeDictionaries、字体资源 |
|
||||
| `ClassIsland/App.axaml.cs` | 512-513、725-727 行(grep) | 强制 zh-CN、AnimationLevel 同步 |
|
||||
| `ClassIsland/App.Services.xaml.cs` | 240-326 行 | 天气图标模板、主题注册、教程注册、TTS provider |
|
||||
| `ClassIsland/MainWindow.axaml` | 全文 686 行 | 窗口透明/圆角/缩放/编辑操作条/层级/ZoomBorder/选择描边 |
|
||||
| `ClassIsland/MainWindow.axaml.cs` | 160-220、370-519、700-819、840-979(grep 全量) | 主题色分支、DPI/安全区/缩放、窗口层级、通知特效缩放 |
|
||||
| `ClassIsland/Controls/MainWindowLine.axaml` | 全文 79 行 | 行可见性、不透明度、悬停淡化、坞位伪类 |
|
||||
| `ClassIsland/Controls/MainWindowLine.cs` | 300-815 行 | 通知状态机、遮罩/覆盖、行淡入、鼠标命中 |
|
||||
| `ClassIsland/Controls/SlantedMaskControl.cs` | 全文 346 行 | 斜切遮罩几何与分块动画参数 |
|
||||
| `ClassIsland/Controls/OobeIntroAnimationControl.axaml` / `.cs` | 全文 | OOBE 入场编排与缓动 |
|
||||
| `ClassIsland/Controls/WorkflowProgressIndicatorItemControl.axaml` | 全文 | 进度条/呼吸/颜色过渡 |
|
||||
| `ClassIsland/Controls/Tutorial/TutorialHighlightControl.axaml` | 全文 | 教程高亮入场 + 循环 |
|
||||
| `ClassIsland/Controls/Tutorial/TutorialSpotlightControl.axaml` | 全文 | 聚光灯遮罩与入场 |
|
||||
| `ClassIsland/Controls/Components/SlideComponent.axaml` | 全文 | 滑动组件 250ms 切换动画 |
|
||||
| `ClassIsland/Controls/Components/RollingComponent.axaml.cs` | 80-179 行 | 滚动速度/暂停/重置 |
|
||||
| `ClassIsland/Controls/Components/CountDownComponent.axaml.cs` | 280-312 行 | 倒计时进度精度取整 |
|
||||
| `ClassIsland/Controls/NotificationEffects/RippleEffect.axaml` / `.cs` | 全文 | 强提醒涟漪几何与 600ms 动画 |
|
||||
| `ClassIsland/Controls/WelcomeWindowIntroControl.xaml` | 全文(218 行) | 欢迎覆盖层 Storyboard(WPF 遗留,仅取数值) |
|
||||
| `ClassIsland/Views/SplashWindow.axaml` / `.cs` | 全文 | 现行启动闪屏布局与 composition 动画 |
|
||||
| `ClassIsland/Views/TopmostEffectWindow.axaml` / `.cs` | 全文 | 特效窗口显示/隐藏与缩放 |
|
||||
| `ClassIsland/Views/WelcomePages/WelcomePage.axaml` | 全文 | 欢迎页淡入与布局 |
|
||||
| `ClassIsland/Views/SettingPages/AppearanceSettingsPage.axaml` | 全文 595 行 | 外观设置全部控件、范围、默认值 |
|
||||
| `ClassIsland/Views/SettingPages/ThemesSettingsPage.axaml` | 全文 368 行 | 主题市场卡片、警告、抽屉、排序 |
|
||||
| `ClassIsland/Views/SettingPages/GeneralSettingsPage.axaml` | 动画级别/闪屏段(grep) | AnimationLevel 三档文案 |
|
||||
| `ClassIsland/Views/SettingPages/UpdateSettingsPage.axaml` | 78-107 行 | 旋转图标 1s 无限动画 |
|
||||
| `ClassIsland/Views/SettingPages/AboutSettingsPage.axaml` | 118-157 行 | 头部 250ms 延迟淡入、品牌渐变色 |
|
||||
| `ClassIsland/Models/Settings.cs` | 字段区(grep 全量默认值)+ 760-1320 行 | 颜色/字体/圆角/透明度/动画级别默认值 |
|
||||
| `ClassIsland/Services/ThemeService.cs` | 全文 76 行 | 主题变体、强调色、强调淡底 10% |
|
||||
| `ClassIsland/Services/XamlThemeService.cs` | 全文 467 行 | 主题包安装/加载/市场/安全区 |
|
||||
| `ClassIsland/Services/WallpaperPickingService.cs` | 全文 379 行(整文件 `#if false`) | 取色算法(停用实现,仅参考) |
|
||||
| `ClassIsland/Assets/Fonts/Fonts.xaml`、`Fonts.axaml`、`LICENSE.txt` | 全文/头部 | 字体族与许可 |
|
||||
| `ClassIsland/Assets/Tutorials/classisland.getStarted.json` | 1-120 行 + 结构 | 教程数据结构 |
|
||||
| `ClassIsland/Assets/XiaomiWeather/xiaomi_weather_status.json` | 全文 | 40 个天气代码→中文名 |
|
||||
| `ClassIsland/Assets/default-subjects.json` | 头部 | 默认 23 科目与固定 GUID |
|
||||
| `ClassIsland/Assets/AsciiLogo.txt`、`Tellings.txt`、`LICENSE.txt` | 全文/头部 | 彩蛋与许可 |
|
||||
| `ClassIsland/Assets/AppLogo.ico`、`ClassIsland.Desktop/Assets/AppLogo.ico` | ICO 头解析 | 图标尺寸条目 |
|
||||
| `ClassIsland/Models/NugetLicenseInfo.cs` | 头部 | 依赖许可清单结构 |
|
||||
|
||||
### 1.2 ClassIsland.Core
|
||||
|
||||
`ThemeBase.axaml`(全文)、`StylesBase.axaml`(全文)、`AppBase.cs`(字体族 grep)、`Abstractions/Services/IThemeService.cs`(全文)、`Abstractions/Services/IXamlThemeService.cs`(全文)、`Abstractions/Controls/MainWindowCustomizableNodeHelper.cs`(全文)、`Assists/MainWindowStylesAssist.cs`(全文)、`Assists/WrapPanelResizingAnimationAssist.cs`(全文)、`Behaviors/StackPanelIntroAnimationBehavior.cs`(全文)、`Behaviors/PopupIntroAnimationBehavior.cs`(全文)、`Controls/DrawerHost.axaml`(全文)、`Controls/VerticalDrawer.axaml`(全文)、`Controls/AnimatedIconButton.axaml`(全文)、`Controls/Shimmer.axaml`(全文)、`Controls/ComponentPresenter.axaml.cs`(190-279 行)、`Controls/NotificationTemplates/RollingTextTemplate.axaml` / `.axaml.cs`、`TwoIconsMaskTemplate.axaml`(全文)、`Converters/SizeDoubleToCornerRadiusConverter.cs`、`Converters/IntToFontWeightConverter.cs`、`Helpers/UI/ControlColorHelper.cs`(全文)、`Models/Components/MainWindowLineSettings.cs`(全文)、`Models/XamlTheme/{ThemeInfo,ThemeManifest,ThemeIndex,ThemeIndexInfo,ThemeRepoManifest}.cs`、`Models/Notification/Templates/RollingTextTemplateData.cs`、`Themes/{Generic,Layers,PopupAnimations,WrapPanelResizingAnimation,StackPanelIntroAnimation,SlidingListBox}.axaml`(全文)、`Themes/MyTeachingTipStyles.axaml`(200-269 行)、`Controls/LessonsControls/LessonsListBox.axaml`(grep)。
|
||||
|
||||
### 1.3 ClassIsland.Shared
|
||||
|
||||
`Enums/AppColorSource.cs`(全文,3 个值:Custom/Wallpaper/System)。
|
||||
|
||||
### 1.4 ClassHelper(映射目标栈)
|
||||
|
||||
`packages/ui/src/tokens.css`(全文)、`packages/ui/src/theme.css`(全文)、`packages/desktop-client/src/renderer/styles/index.css`(1-160、560-1012 行 + token/keyframes grep)、`renderer/composables/motion.ts`(全文)、`island/spring.ts`(全文)、`island/squircle.ts`(全文)、`island/classic-island.css`(1-120 行 + grep)、`island/custom-island.css`(1-120 行)、`island/IslandApp.vue`(grep)、`main/island.ts`(1655-1734 行 + grep)、`packages/shared/src/motion.ts`(全文)。
|
||||
|
||||
### 1.5 全仓库检索
|
||||
|
||||
- `AnimationLevel` 全部 12 处命中(App.axaml.cs、IThemeService、GeneralSettingsPage、StackPanelIntroAnimationBehavior、PopupIntroAnimationBehavior、WrapPanelResizingAnimationAssist、MainWindowLine、ComponentPresenter、DrawerHost、VerticalDrawer)→ part 14 §14.0.1。
|
||||
- `Animation/Transition/KeyFrame/Easing/Duration/Transitions` 共 249 处 axaml 命中 → 逐条筛选出 99 条有效动效。
|
||||
- 全仓库 `#RRGGBB` 共 46 处命中 → part 03 §3.1。
|
||||
- `Storyboard/BeginStoryboard` 46 处命中,其中多数为 `#if false` 的 WPF 遗留代码(SplashControl、WelcomeWindowIntroControl、LoadingMask、ExcelImportWindow 等),仅作为动画数值参考。
|
||||
|
||||
## 2. Token 对照表(ClassIsland → 建议 CSS 变量 → ClassHelper 既有变量)
|
||||
|
||||
| ClassIsland 资源/设置 | 值/默认 | 建议 CSS 变量 | ClassHelper 既有 | 落点 |
|
||||
|---|---|---|---|---|
|
||||
| 强调色 `PrimaryColor` | `#00BFFF` | `--ci-accent` | `--ch-ui-primary` / `--ch-accent` / `--el-color-primary` | `ui/src/theme.css` |
|
||||
| 强调淡底 `CustomizedAccentBarBackground1Brush` | accent@10% | `--ci-accent-soft` | `--ch-accent-soft` | `theme.css` |
|
||||
| 强调色(深色) | 系统/accent | 同变量 | `--ch-accent: #5aabec`(深色示例) | `renderer/styles/index.css:109` |
|
||||
| 文本 5 级 | 255/218/197/135/93 alpha | `--ci-text-1..5` | `--ch-text` / `--ch-text-secondary` / `--ch-text-tertiary` | 需新增 2 级 |
|
||||
| 表面基色 | `SolidBackgroundFillColorBase` | `--ci-bg-base` | `--ch-bg`(`#f3f3f3` / `#161719`) | `index.css:27,114` |
|
||||
| 表面次级 | `...Secondary` | `--ci-bg-secondary` | `--ch-layer` | `index.css:28,115` |
|
||||
| 表面三级 | `...Tertiary` | `--ci-bg-tertiary` | `--ch-layer-alt` | `index.css:30,117` |
|
||||
| 描边 | `ControlElevationBorderBrush` | `--ci-stroke-island` | `--ch-border` / `--ch-border-strong` | `index.css:34-35` |
|
||||
| 分隔线 | `DividerStrokeColorDefaultBrush` | `--ci-stroke-divider` | `--ch-divider` | `index.css:36` |
|
||||
| 雾面/遮罩 | `SmokeFillColorDefaultBrush` | `--ci-smoke` | (无,需新增) | 新增 |
|
||||
| 岛圆角 | 8px(0–20 可调) | `--ci-radius-island` | `--ch-radius-card: 8px` | `index.css:51` |
|
||||
| 卡片圆角 | 4px | `--ci-radius-card` | `--ch-radius-control: 4px` | `index.css:52` |
|
||||
| 岛高度 | 40px | `--ci-island-height` | (无;ClassHelper 岛高由外观配置) | 新增 |
|
||||
| 岛行间距 | 5px | `--ci-line-gap` | `--ch-ui-gap: 16px`(不适用) | 新增 |
|
||||
| 背景不透明度 | 0.5 | `--ci-island-bg-opacity` | (无) | 新增 |
|
||||
| 淡出态 | 0.05 | `--ci-island-fade-opacity` | (无) | 新增 |
|
||||
| 投影(Fluent) | `0 4 8 2 #48000000` | `--ci-shadow-island` | `--ch-shadow-card` / `--ch-shadow-flyout` | 需新增更强投影 |
|
||||
| 文本主色(深色) | `#e8e8ea` | `--ci-text-1` | `--ch-text: #e8e8ea` | `index.css:124` |
|
||||
| 环境背景(深色) | `#161719` | `--ci-bg-base` | `--ch-bg` | `index.css:114` |
|
||||
| 字号 4 档 | 14/16/18/20 | `--ci-fs-secondary/body/emphasized/large` | `--el-font-size-base:13px`、`--ch-font-scale` | `index.css:97-103` |
|
||||
| 字重 | 500 | `--ci-font-weight`(或行内覆盖) | (无) | 新增 |
|
||||
| 字体族 | HarmonyOS Sans SC 栈 | `--ci-font` | 岛用 `--island-font`、外壳用系统字体 | `classic-island.css:22-25` |
|
||||
| 动效时长 | 90/140/200/320 | `--ci-dur-*` | `--ch-dur-instant/fast/base/slow/page` | `shared/src/motion.ts:169-175` |
|
||||
| 缓动 | 多条 | `--ci-ease-*` | `--ch-ease-out/in-out/drawer` | `motion.ts:24-28` |
|
||||
| 弹簧 | stiffness .10 / damping .68 | JS `SpringValue` | 同左 | `island/spring.ts` |
|
||||
| 层级哨兵 | 33550336 | `--ci-z-sentinel` | 无(ClassHelper 用 10000 引导层) | 新增 |
|
||||
| 安全区 | 0 / 20px(Fluent) | `--ci-safe-area-y` | 无 | 新增 |
|
||||
|
||||
**冲突提醒(供 Lead 汇总时统一)**:`--ci-shadow-island` 与 ClassHelper 的 `--ch-shadow-card` 语义不同(前者是「悬浮岛投影」,后者是「卡片微投影」),不得合并;`--ci-accent-soft` 与 `--ch-accent-soft` 可统一,但 alpha 不同(ClassIsland 10%,ClassHelper 8%),建议取 10% 并在 part 09 说明。
|
||||
|
||||
## 3. 与其他 part 的一致性约定(已核对)
|
||||
|
||||
- 岛高度 **40px**、圆角默认 **8px**、背景不透明度 **0.5**、行间距默认 **5px**、字号 **14/16/18/20**、动画级别默认 **1**:part 03/04/10 必须与此一致。
|
||||
- 提醒遮罩动画的时长/延迟(Fluent:360/120/260/250/750/600/100ms;Classic:200/100/200/100ms)只在 part 14 定义,part 07 引用时不得改数值。
|
||||
- 主题包 `manifest.yml` 字段与 part 09 §9.3.2 为准;part 12(插件)如需复用市场索引结构,应引用该表而不是另立字段。
|
||||
- 窗口透明/亚克力规则:part 04 的窗口规格必须遵守 part 03 §3.5 的「禁止 setBackgroundMaterial」约束。
|
||||
|
||||
## 4. 未决问题与缺口
|
||||
|
||||
| 编号 | 问题 | 影响 | 建议处理 |
|
||||
|---|---|---|---|
|
||||
| Q1 | FluentAvalonia 的具体色值(`SolidBackgroundFillColorBaseMemo`、`TextFillColorPrimaryBrush`、`ControlElevationBorderBrush` 等)不在本仓库(NuGet 依赖),part 03 中相关值标注【推断】 | 颜色实现可能与真实 ClassIsland 有肉眼差异 | 由 stack 组拉取 FluentAvalonia 对应版本源码/主题字典核对;或由用户提供截图取色 |
|
||||
| Q2 | `WallpaperPickingService` 整文件 `#if false`,DI 与调用点均被注释,设置页「系统壁纸/屏幕主题色」两项被禁用隐藏 | 壁纸取色是否属于必做功能存在歧义 | 建议 Lead 在总纲明确:默认不实现,或按 part 09 §9.6 实现为实验特性;算法已给出可复现公式 |
|
||||
| Q3 | 教程内容 `RightButtonActions[].Kind` 枚举值(2/5/6/8…)语义未在本次读取的源码中确认(属 part 11 教程章节) | 教程按钮行为实现需要枚举映射 | 由 windows 组在 part 11 补齐 `TutorialActionKind` 映射表;part 15 只声明结构 |
|
||||
| Q4 | 部分 Avalonia 缓动(Sine/Quadratic/Cubic/Exponential)到 CSS cubic-bezier 的换算为近似 | 动画手感有细微差异 | 已逐条标注【推断】;如需精确可改用 `linear()` 采样或 WAAPI 自定义缓动函数 |
|
||||
| Q5 | `ClassicTheme` 的 `Easing="0,0 0,1"` 是 Avalonia `KeySpline` 二元组语法,换算为 `cubic-bezier(0,0,0,1)`;个别处(DrawerHost/VerticalDrawer/关于页)语义需实机验证 | 抽屉动效可能偏「硬」 | 实现后与截图/录屏对照,偏硬可回退为 `ease-out` |
|
||||
| Q6 | 贴纸(HoYoStickers)与 SF Symbols 字体的许可边界未在仓库内声明 | 分发合规风险 | 由 Lead 在交付说明中标注:贴纸为同人彩蛋、SF Symbols 需授权;或替换为可自由分发的图标集 |
|
||||
| Q7 | 源码部分动画存在于 `#if false` 的 WPF 遗留实现(SplashControl、WelcomeWindowIntroControl、LoadingMask) | 数值可信度低于现行 Avalonia 实现 | part 14 已优先采用现行 Avalonia composition 实现(SplashWindow、OobeIntroAnimationControl)数值;遗留 Storyboard 仅作参考 |
|
||||
| Q8 | `RootLayoutTransformControl` 的缩放补偿在 `NewWindowPosUpdateImpl` 中赋值但未参与布局(`GridRootLeft/Top` 只在 Old 实现使用) | 界面缩放时岛的水平偏移算法需要重新定 | 由 ui-island 在 part 04 给出最终窗口缩放算法,part 03 §3.7 只给约束 |
|
||||
| Q9 | 主题预览图 1920×350 与主题卡 328×150 的裁切策略未在源码明确(`UniformToFill` + 渐变遮罩) | 卡片可能裁掉主题名称区域 | part 09 已给渐变遮罩方案;实现时以「名称/作者永远可见」为准 |
|
||||
| Q10 | `--ci-*` 与 `--ch-*` 是否合并、以谁为单一来源 | 可能出现两套 token 并存 | 建议:`--ch-*` 为应用外壳唯一来源,`--ci-*` 引用 `--ch-*` 派生岛层;由 stack 在 part 02 定稿 |
|
||||
| Q11 | part 04 §4.4 的别名表把 `--island-opacity`(默认 0.5)映射为 `--ci-line-opacity`;但源码里「背景不透明度 0.5」与「行整体不透明度 1.0」是两个不同字段(`Settings.Opacity` vs `MainWindowLineSettings.Opacity`) | Lead 汇总时会出现语义混淆 | 已在 part 03 §3.5 定义 `--ci-island-opacity`(=0.5,背景)与 `--ci-line-opacity`(=1.0,行级);建议 Lead 把 part 04 别名表该行改为 `--ci-island-opacity` |
|
||||
| Q12 | part 04 引入了 `--ci-progress-height: 3px`,而 part 03 初稿未定义;`--ci-component-gap` 在 part 04 被当作「12px 相邻间距」使用 | 两处 token 命名/语义不一致 | 已在 part 03 §3.4 补 `--ci-progress-height: 3px`,并把 `--ci-component-gap` 改为 12px(相邻间距,单侧 margin = 6px),与 part 04 的 `calc(/2)` 用法一致 |
|
||||
|
||||
## 5. 产出与自检
|
||||
|
||||
| 文件 | 中文字数(CJK) | 条目数 | 验收小节 |
|
||||
|---|---|---|---|
|
||||
| `parts/03-design-tokens.md` | 4531 | — | §3.11 共 12 条 |
|
||||
| `parts/09-themes.md` | 4499 | — | §9.12 共 12 条 |
|
||||
| `parts/14-animations.md` | 6123 | 99 条动效 | §14.9 共 10 条 |
|
||||
| `parts/15-assets.md` | 4098 | — | §15.12 共 11 条 |
|
||||
|
||||
自检结论:
|
||||
- 未执行任何构建/运行/截图/安装命令;未修改 `repos/` 下文件。
|
||||
- 所有关键数值均标注 `相对路径:行号`;无法从仓库确认的值标注【推断】并在 §4 记录。
|
||||
- 术语与 `analysis/00-brief.md` §5 一致(主界面/主界面行/组件/档案/课表/时间表/提醒/主题/设置)。
|
||||
- 每份 part 均以简体中文祈使句写成,含「验收标准」,可直接作为 ChatGPT 实现任务书的一部分。
|
||||
@@ -0,0 +1,239 @@
|
||||
# features(Part 06/07/08)分析备注
|
||||
|
||||
负责人:features。产出:`parts/06-schedule-profile.md`、`parts/07-notifications.md`、`parts/08-automation.md`。
|
||||
本文件记录:已读源文件清单、关键枚举/默认值表(供 Lead 汇总时交叉校验)、未决问题与缺口。全部为静态阅读结论,未构建、未运行、未截图。
|
||||
|
||||
## 1. 已读文件清单(相对 `D:\clword`)
|
||||
|
||||
### 1.1 档案 / 课表 / 时间表(Part 06)
|
||||
|
||||
| 文件 | 说明 / 关键行 |
|
||||
|---|---|
|
||||
| `repos/ClassIsland/ClassIsland.Shared/Models/Profile/Profile.cs` | 档案根模型(484 行):字段默认值 17-32,内置课表群 44-59,解散/删除群 104-137,科目编辑集合 139-217,临时层/临时课表/临时群 313-449,`OrderedSchedules` 468-477 |
|
||||
| `repos/ClassIsland/ClassIsland.Shared/Models/Profile/ClassPlan.cs` | 课表(608 行):默认值 15-27,`ValidTimeLayoutItems` 双向裁剪 54-98,`RefreshClassesList` 451-491,`RefreshIsChangedClass` 496-513,`RemoveTimePointSafe` 515-522 |
|
||||
| `repos/ClassIsland/ClassIsland.Shared/Models/Profile/TimeLayout.cs` | 时间表(298 行):默认名 17,增删时间点 188-235,`Layouts` 254-267 |
|
||||
| `repos/ClassIsland/ClassIsland.Shared/Models/Profile/TimeLayoutItem.cs` | 时间点(256 行):Start/End 62-93,TimeType 文档 119-138,BreakName 175-191,ActionSet 196-205,CompareTo 212-241 |
|
||||
| `repos/ClassIsland/ClassIsland.Shared/Models/Profile/ClassInfo.cs` | 课程项(122 行) |
|
||||
| `repos/ClassIsland/ClassIsland.Shared/Models/Profile/Subject.cs` | 科目(141 行):自动 Initial 19-30,三个内置科目 79-101,复姓表 14、`GetFirstName` 107-140 |
|
||||
| `repos/ClassIsland/ClassIsland.Shared/Models/Profile/TimeRule.cs` | 触发规则(70 行):默认 WeekDay=0 / Div=0 / DivTotal=2 |
|
||||
| `repos/ClassIsland/ClassIsland.Shared/Models/Profile/ClassPlanGroup.cs` | 课表群(50 行):两个内置 GUID |
|
||||
| `repos/ClassIsland/ClassIsland.Shared/Models/Profile/OrderedSchedule.cs` | 预定课表(25 行) |
|
||||
| `repos/ClassIsland/ClassIsland.Shared/Enums/TempClassPlanGroupType.cs` | Override / Inherit |
|
||||
| `repos/ClassIsland/ClassIsland.Shared/Enums/TimeState.cs` | None/OnClass/PrepareOnClass/Breaking/AfterSchool |
|
||||
| `repos/ClassIsland/ClassIsland/Services/LessonsService.cs` | 课程服务(646 行):50ms 计时器 39-45,课表选择 143-201,tick 主逻辑 373-527,`LoadCurrentClassPlan` 549-580,`CheckClassPlan` 582-607,周次计算 619-635,`GetClassIndex` 531-541 |
|
||||
| `repos/ClassIsland/ClassIsland/Services/ProfileService.cs` | 档案服务(438 行):路径 34-53,集控合并 78-137,加载/保存 139-227,临时层 235-328,转正 335-360,临时群 362-415,信任 417-422 |
|
||||
| `repos/ClassIsland/ClassIsland/Services/ProfileAnalyzeService.cs` | 对象图分析(212 行) |
|
||||
| `repos/ClassIsland/ClassIsland/Views/ProfileSettingsWindow.axaml` | 档案编辑窗(2004 行):窗口参数 23-30,课表信息面板 53-140,时间表面板 202-232,临时课表/临时层 235-338,课表群 342-413,换课 Flyout 415-446,临时层 Flyout 448+ |
|
||||
| `repos/ClassIsland/ClassIsland/Views/ProfileSettingsWindow.axaml.cs` | 交互逻辑(1671 行):`Open` 与页索引 186-262,保存于关闭 264-274,新增时间点 983-1099,调课 1414-1510,导入导出 1565-1668 |
|
||||
| `repos/ClassIsland/ClassIsland/Views/ClassPlanDetailsWindow.axaml` | 课表详细信息窗(199 行) |
|
||||
| `repos/ClassIsland/ClassIsland/Controls/TimeRuleEditControl.axaml` | 单双周/星期 Chip UI(54 行) |
|
||||
| `repos/ClassIsland/ClassIsland/Controls/WeekOffsetSettingsControl.axaml.cs` | 轮换偏移正/反算(132 行) |
|
||||
| `repos/ClassIsland/ClassIsland.Shared/Extensions/CsesExtensions.cs` | CSES 双向转换(167 行) |
|
||||
| `repos/ClassIsland/ClassIsland/Controls/ProfileTransferProviders/CsesImportProvider.cs` | CSES 导入(72 行) |
|
||||
| `repos/ClassIsland/ClassIsland/Controls/ProfileTransferProviders/ClassIsland1ImportProvider.cs` | 1.x 导入(58 行) |
|
||||
| `repos/ClassIsland/ClassIsland/Views/ExcelImportWindow.xaml.cs` | **整文件 `#if false`(1 行处),WPF 遗留**(824 行) |
|
||||
| `repos/ClassIsland/ClassIsland/Views/ExcelExportWindow.xaml.cs` | **整文件 `#if false`(1-539 行)** |
|
||||
| `repos/ClassIsland/ClassIsland/App.Services.xaml.cs` | 注册表:窗口 109/145/148/198/204,提醒提供方 198-202,触发器 240-251,规则 253-267,行动 269-276,导入导出 292-296 |
|
||||
|
||||
### 1.2 提醒(Part 07)
|
||||
|
||||
| 文件 | 说明 / 关键行 |
|
||||
|---|---|
|
||||
| `repos/ClassIsland/ClassIsland/Services/NotificationHostService.cs` | 提醒主机(542 行):优先队列 41,提供方注册 79-114,Setup 128-155,Show 157-176,入队 178-191,链式 205-254,渠道注册 273-284,取消全部 322-335,推送/弹出 337-419,消费者注册 436-470,重新入队 488-522 |
|
||||
| `repos/ClassIsland/ClassIsland/Services/NotificationWorkerService.cs` | 播放会话(250 行):设置三层覆盖 109-124,计时 82-107,语音/音效 178-208,状态机 211-234 |
|
||||
| `repos/ClassIsland/ClassIsland.Core/Models/Notification/NotificationRequest.cs` | v2 请求(200 行) |
|
||||
| `repos/ClassIsland/ClassIsland.Core/Models/Notification/NotificationContent.cs` | 内容与三个模板工厂(217 行) |
|
||||
| `repos/ClassIsland/ClassIsland.Shared/Models/Notification/NotificationPriority.cs` | 比较器(63 行,含 IsPriorityOverride 反常行为) |
|
||||
| `repos/ClassIsland/ClassIsland.Shared/Models/Notification/NotificationSettings.cs` | 提醒设置默认值(116 行) |
|
||||
| `repos/ClassIsland/ClassIsland.Shared/Models/Notification/NotificationProviderRegisterInfo.cs` | 提供方注册信息(57 行) |
|
||||
| `repos/ClassIsland/ClassIsland.Shared/Models/Notification/NotificationRequest.cs` | 旧版(`[Obsolete]`,249 行) |
|
||||
| `repos/ClassIsland/ClassIsland.Core/Enums/Notification/NotificationState.cs` | 播放状态(32 行) |
|
||||
| `repos/ClassIsland/ClassIsland.Shared/Enums/NotificationModes.cs` | Disabled/EnabledForce/Default |
|
||||
| `repos/ClassIsland/ClassIsland.Core/Abstractions/INotificationConsumer.cs` | 消费者契约 |
|
||||
| `repos/ClassIsland/ClassIsland.Core/Abstractions/Services/NotificationProviders/NotificationProviderBase.cs` | 提供方基类(198 行) |
|
||||
| `repos/ClassIsland/ClassIsland.Core/Abstractions/Services/NotificationProviders/NotificationChannel.cs` | 渠道(104 行) |
|
||||
| `repos/ClassIsland/ClassIsland.Shared/Interfaces/INotificationProvider.cs` | 默认音效 Uri(37 行) |
|
||||
| `repos/ClassIsland/ClassIsland.Core/Attributes/NotificationProviderInfo.cs` / `NotificationChannelInfo.cs` | 特性定义 |
|
||||
| `repos/ClassIsland/ClassIsland/Services/NotificationProviders/ClassNotificationProvider.cs` | 上下课提醒(325 行) |
|
||||
| `.../AfterSchoolNotificationProvider.cs` | 放学提醒(61 行) |
|
||||
| `.../WeatherNotificationProvider.cs` | 天气提醒(173 行) |
|
||||
| `.../ManagementNotificationProvider.cs` | 集控提醒(81 行) |
|
||||
| `.../ActionNotificationProvider.cs` | 行动提醒(17 行,仅作为发送源) |
|
||||
| `repos/ClassIsland/ClassIsland/Models/NotificationProviderSettings/ClassNotificationSettings.cs` | 上下课设置默认值(199 行) |
|
||||
| `.../WeatherNotificationProviderSettings.cs` | 天气设置默认值(70 行) |
|
||||
| `.../AfterSchoolNotificationProviderSettings.cs` | 放学设置默认值(33 行) |
|
||||
| `repos/ClassIsland/ClassIsland.Controls/NotificationProviders/*.axaml` | 气泡内容布局:`ClassNotificationProviderControl.axaml`(104 行)、`AfterSchoolNotificationProvider.axaml`(30 行)、`WeatherNotificationProviderControl.axaml`(47 行) |
|
||||
| `repos/ClassIsland/ClassIsland/Controls/MainWindowLine.cs` | 消费者与播放流程(815 行):`ReceiveNotifications` 639-656,模板键解析 658-665,中心点 667-680,`ProcessNotification` 682-811,`AcceptsNotificationRequests` 814 |
|
||||
| `repos/ClassIsland/ClassIsland/Controls/MainWindowLine.axaml` | 行样式:`IslandContainerHeight=40`(16 行),进度绑定 77 |
|
||||
| `repos/ClassIsland/ClassIsland/XamlThemes/FluentTheme/Styles.axaml` | 气泡模板与动画(120-197、275-449);`SlantedMaskControl` 参数 175-180 |
|
||||
| `repos/ClassIsland/ClassIsland/XamlThemes/ClassicTheme/Styles.axaml` | 经典主题同类样式(136-330) |
|
||||
| `repos/ClassIsland/ClassIsland/Controls/SlantedMaskControl.cs` | 斜切遮罩(346 行,含 5 区域权重与绘制) |
|
||||
| `repos/ClassIsland/ClassIsland/Controls/NotificationEffects/RippleEffect.axaml(.cs)` | 强提醒涟漪(32/113 行) |
|
||||
| `repos/ClassIsland/ClassIsland/Views/TopmostEffectWindow.axaml(.cs)` | 特效窗口(35/135 行),`UpdateWindowPos` 100-109 |
|
||||
| `repos/ClassIsland/ClassIsland/ViewModels/TopmostEffectWindowViewModel.cs` | 特效控件集合(24 行) |
|
||||
| `repos/ClassIsland/ClassIsland/MainWindow.axaml.cs` | 置顶锁 1056-1092,清除全部 1171-1174 |
|
||||
| `repos/ClassIsland/ClassIsland/MainWindow.axaml` | 右键「清除全部提醒」86-94,行「此行可以显示提醒」425-433 |
|
||||
| `repos/ClassIsland/ClassIsland/Views/ClearNotificationButtonWindow.xaml(.cs)` | **`#if false` 遗留,仅 15/18 行** |
|
||||
| `repos/ClassIsland/ClassIsland/Services/AudioService.cs` | 音频设备共享与播放(143 行) |
|
||||
| `repos/ClassIsland/ClassIsland/Services/SpeechService/SystemSpeechService.cs` | 系统 TTS 音量映射 |
|
||||
| `.../EdgeTtsService.cs` | Edge TTS 音色/缓存/音量 |
|
||||
| `repos/ClassIsland/ClassIsland/Views/SettingPages/NotificationSettingsPage.axaml` | 提醒设置页(497 行) |
|
||||
|
||||
### 1.3 自动化(Part 08)
|
||||
|
||||
| 文件 | 说明 / 关键行 |
|
||||
|---|---|
|
||||
| `repos/ClassIsland/ClassIsland/Services/AutomationService.cs` | 自动化服务(465 行):时间点行动 84-108,触发 112-133,恢复 138-167,配置加载 173-233,工作流加载 237-328,触发器加载 334-436 |
|
||||
| `repos/ClassIsland/ClassIsland/Services/ActionService.cs` | 行动服务(277 行):Invoke/Revert/Interrupt 20-91,行动项执行 93-135,可变列表迭代 137-173,迁移 179-203,菜单树 208-260 |
|
||||
| `repos/ClassIsland/ClassIsland/Services/RulesetService.cs` | 规则求值(163 行) |
|
||||
| `repos/ClassIsland/ClassIsland/Services/WeatherService.cs` | 天气规则处理(460 行):规则注册 64-68,各规则 93-221,刷新与预警去重 236-403 |
|
||||
| `repos/ClassIsland/ClassIsland/Services/WindowRuleService.cs` | 窗口规则处理(111 行) |
|
||||
| `repos/ClassIsland/ClassIsland.Core/Models/Automation/Workflow.cs` | 工作流(33 行) |
|
||||
| `.../TriggerSettings.cs` | 触发器设置(61 行) |
|
||||
| `repos/ClassIsland/ClassIsland.Shared/Models/Automation/ActionSet.cs` | 行动组(128 行) |
|
||||
| `.../ActionItem.cs` | 行动项(99 行) |
|
||||
| `repos/ClassIsland/ClassIsland.Core/Models/Ruleset/{Ruleset,RuleGroup,Rule,StringMatchingSettings}.cs` | 规则集模型 |
|
||||
| `repos/ClassIsland/ClassIsland.Core/Enums/RulesetLogicalMode.cs` | Or/And |
|
||||
| `repos/ClassIsland/ClassIsland.Shared/Enums/ActionSetStatus.cs` | 4 状态 |
|
||||
| `repos/ClassIsland/ClassIsland.Core/Abstractions/Automation/{TriggerBase,ActionBase}.cs` | 基类契约 |
|
||||
| `repos/ClassIsland/ClassIsland.Core/Attributes/{TriggerInfo,ActionInfo}.cs` | 注册特性 |
|
||||
| `repos/ClassIsland/ClassIsland/Services/Automation/Triggers/*.cs` | 12 个触发器(逐文件已读) |
|
||||
| `repos/ClassIsland/ClassIsland/Services/Automation/Actions/*.cs` | 7 个行动(逐文件已读) |
|
||||
| `repos/ClassIsland/ClassIsland/Models/Automation/Triggers/*.cs` | 5 个触发器设置模型 |
|
||||
| `repos/ClassIsland/ClassIsland/Models/Actions/*.cs` | 6 个行动设置模型 |
|
||||
| `repos/ClassIsland/ClassIsland/Models/Rules/*.cs` | 6 个规则设置模型 |
|
||||
| `repos/ClassIsland/ClassIsland/Views/SettingPages/AutomationSettingsPage.axaml(.cs)` | 自动化设置页(402/167 行) |
|
||||
| `repos/ClassIsland/ClassIsland/Models/Settings.cs` | 全局默认值(2655 行,按行号引用) |
|
||||
|
||||
## 2. 关键枚举 / 默认值总表(供交叉校验)
|
||||
|
||||
### 2.1 枚举
|
||||
|
||||
| 名称 | 值 | 证据 |
|
||||
|---|---|---|
|
||||
| `TimeLayoutItem.TimeType` | 0 上课 / 1 课间 / 2 分割线 / 3 行动 | `TimeLayoutItem.cs:120-138,246-253` |
|
||||
| `TimeState` | 0 None / 1 OnClass / 2 PrepareOnClass(预留) / 3 Breaking / 4 AfterSchool | `TimeState.cs:6-27` |
|
||||
| `TempClassPlanGroupType` | 0 Override / 1 Inherit | `TempClassPlanGroupType.cs:6-16` |
|
||||
| `NotificationState` | None/Queued/Playing/Paused/Cancelled/Completed | `NotificationState.cs:6-31` |
|
||||
| `NotificationModes` | Disabled=0 / EnabledForce=1 / Default=2 | `NotificationModes.cs:6-19` |
|
||||
| `ActionSetStatus` | Normal / Invoking / IsOn / Reverting | `ActionSetStatus.cs:6-24` |
|
||||
| `RulesetLogicalMode` | Or / And | `RulesetLogicalMode.cs:6-15` |
|
||||
| `WindowStatusRuleSettings.State` | 0 正常 / 1 最大化 / 2 最小化 / 3 全屏(默认 1) | `WindowStatusRuleSettings.cs:7-27` |
|
||||
| `RunActionRunType` | Application/Command/File/Folder/Url(字符串枚举) | `RunActionSettings.cs:19-49` |
|
||||
| `WeatherNotificationActionSettings.NotificationKind` | 0 三天预报 / 1 预警 / 2 逐小时 | `WeatherNotificationActionSettings.cs:7` |
|
||||
|
||||
### 2.2 固定 GUID / ID
|
||||
|
||||
- 默认课表群 `ACAF4EF0-E261-4262-B941-34EA93CB4369`;全局课表群 `00000000-0000-0000-0000-000000000000`(`ClassPlanGroup.cs:44-49`)。
|
||||
- 提醒提供方:上下课 `08F0D9C3-C770-4093-A3D0-02F3D90C24BC`、放学 `8FBC3A26-6D20-44DD-B895-B9411E3DDC51`、天气 `7625DE96-38AA-4B71-B478-3F156DD9458D`、集控 `0117fb4f-5374-434a-97fb-4f5374634a07`、行动 `4B12F124-8585-43C7-AFC5-7BBB7CBE60D6`。
|
||||
- 渠道:准备上课 `CDDFE7FF-B904-4C73-B458-82793B2F66E9`、上课 `AFF5B9A4-037C-4A71-8563-C9EA87DDA75C`、下课 `77C9F3FB-0A2A-4B22-BDDF-3C333462B2F9`。
|
||||
- 触发器 12 个 ID、行动 8 个 ID、规则 15 个 ID:见 Part 08 的表格(证据集中在 `App.Services.xaml.cs:240-276` 与各触发器/行动源文件)。
|
||||
|
||||
### 2.3 关键默认值(Part 06/07/08 交叉引用)
|
||||
|
||||
| 设置 | 默认 | 证据 |
|
||||
|---|---|---|
|
||||
| `SelectedProfile` | `"Default.json"` | Settings.cs:66 |
|
||||
| `SingleWeekStartTime` | 今天所在周的周日 | Settings.cs:37-42 |
|
||||
| `MultiWeekRotationMaxCycle` | 4 | Settings.cs:61 |
|
||||
| `MultiWeekRotationOffset` | `[-1,-1,0,0,0]` | Settings.cs:60 |
|
||||
| `DefaultOnClassTimePointMinutes` | 40 | Settings.cs:108 |
|
||||
| `DefaultBreakingTimePointMinutes` | 10 | Settings.cs:109 |
|
||||
| `ClassPrepareNotifySeconds` | 60 | Settings.cs:43 |
|
||||
| `IsProfileEditorClassInfoSubjectAutoMoveNextEnabled` | true | Settings.cs:181 |
|
||||
| `IsSwapMode` | true | Settings.cs:210 |
|
||||
| `ExpIsExcelImportEnabled` | false | Settings.cs:113 |
|
||||
| 档案窗口 | 1100×600,MinWidth 750 | ProfileSettingsWindow.axaml:27-28 |
|
||||
| 课表详情窗口 | 800×500 | ClassPlanDetailsWindow.axaml:17 |
|
||||
| `IsNotificationEnabled` | true | Settings.cs:91 |
|
||||
| `AllowNotificationSpeech` | false | Settings.cs:153 |
|
||||
| `AllowNotificationEffect` | true | Settings.cs:154 |
|
||||
| `AllowNotificationSound` | false | Settings.cs:155 |
|
||||
| `AllowNotificationTopmost` | true | Settings.cs:156 |
|
||||
| `NotificationSoundVolume` | 1.0 | Settings.cs:182 |
|
||||
| `SpeechVolume` | 1.0 | Settings.cs:136 |
|
||||
| `EdgeTtsVoiceName` | `zh-CN-XiaoxiaoNeural` | Settings.cs:138 |
|
||||
| `IsNotificationSoundEnabled`(全局兜底层) | true | Settings.cs:144 |
|
||||
| `NotificationEffectRenderingScale` | 1.0 | Settings.cs:150 |
|
||||
| `NotificationUseStandaloneEffectUiThread` | true | Settings.cs:1837 |
|
||||
| `AnimationLevel` | 1 | Settings.cs:1851 |
|
||||
| 遮罩/正文默认时长 | 5s / 5s | NotificationContent.cs:22-23 |
|
||||
| 行高 `IslandContainerHeight` | 40 | MainWindowLine.axaml:16 |
|
||||
| `IsAutomationEnabled` / `IsAutomationWarningVisible` / `CurrentAutomationConfig` | false / true / `"Default"` | Settings.cs:160-162 |
|
||||
| `IsOnClassNotificationEnabled` 等三个上下课开关 | true | ClassNotificationSettings.cs:7-9 |
|
||||
| 室内/户外提前量 | 60 / 600 秒 | ClassNotificationSettings.cs:10-11 |
|
||||
| `WeatherAlertSpeed` | 7.0 | WeatherNotificationProviderSettings.cs:14 |
|
||||
| 天气显示模式(预警/预报) | Disabled / Disabled | WeatherNotificationProviderSettings.cs:10-11 |
|
||||
| 放学提醒 `IsEnabled` / `NotificationMsg` | true / `"今天的课程已结束,请同学们有序离开。"` | AfterSchoolNotificationProviderSettings.cs:9-10 |
|
||||
| `NotificationActionSettings.MaskDurationSeconds` / `ContentDurationSeconds` | 5.0 / 10.0 | NotificationActionSettings.cs:14-15 |
|
||||
| `SleepActionSettings.Value` | 5 秒 | SleepActionSettings.cs:6 |
|
||||
| `PreTimePointTriggerSettings` | `TargetState=OnClass`, `TimeSeconds=60` | PreTimePointTriggerSettings.cs:9-11 |
|
||||
| `CronTriggerSettings.CronExpression` | `"* * * * *"` | CronTriggerSettings.cs:7 |
|
||||
| `ActionSet.Name` / `IsEnabled` / `IsRevertEnabled` | `"新行动组"` / true / false | ActionSet.cs:77-93 |
|
||||
|
||||
## 3. 未决问题 / 缺口(需 Lead 决策或后续补读)
|
||||
|
||||
1. **提醒优先级插队语义反常**:`NotificationPriority.CompareTo` 在 `IsPriorityOverride=true` 时返回 1(`NotificationPriority.cs:47-50`),在 .NET 最小堆中意味着**更晚**出队,与「紧急插队」直觉相反。Part 07 已按「显式定义 + 标注【推断】为历史取反问题」处理;若 Lead 要求逐位一致,需在总纲统一说明。
|
||||
2. **`ClearNotificationButtonWindow` 为 `#if false` 遗留**:当前版本没有「清除提醒浮动按钮窗口」;Part 07 明确要求不得实现它,改用右键菜单「清除全部提醒」。若产品要求必须有,属新增功能。
|
||||
3. **Excel 导入/导出整体被 `#if false` 屏蔽**(两个窗口 + DI 注册 + `ExpIsExcelImportEnabled=false`)。Part 06 已把它标为非首版必做,并给出【推断】格式建议;当前可用的导入导出是 CSES / ClassIsland 1.x / Class Widgets 1.2 / 导出 CSES(`App.Services.xaml.cs:292-296`)。
|
||||
4. **「静音时段」不存在**:Settings 与提醒链路中没有任何免打扰时段字段,只有 `-q` 静默启动后 10 秒丢弃提醒(`MainWindowLine.cs:698-704`)。Part 07 已声明不得虚构,并给出可选扩展模型(标注【推断】)。
|
||||
5. **强提醒渲染缩放自动推算公式缺失**:`IsNotificationEffectRenderingScaleAutoSet=true` 时的具体系数未在 `TopmostEffectWindow.cs` 中给出,Part 07 标【推断】。
|
||||
6. **Class Widgets 1.2 导入转换逻辑未细读**:`ClassWidgetsProfileTransferHelper.cs` 尚未逐行阅读,Part 06 只按注册表与通用导入契约要求实现(文件名/流程/失败提示),未写字段映射细则。若需要像素级导入转换,需补读该文件。
|
||||
7. **`ClassIslandV1ProfileTransferHelper` 与 `ClassWidgetsProfileTransferHelper`** 同样未逐行读;Part 06 只覆盖 CSES 的完整映射算法。
|
||||
8. **时间线缩放常量缺失**:`ProfileSettingsWindow.axaml.cs` 的 ZoomIn/ZoomOut 只做 UI 事件,未读取具体缩放范围常量,Part 06 标【推断】为 0.5x–3x / 步长 0.1。
|
||||
9. **档案 JSON 损坏的容错细节**:`ConfigureFileHelper.LoadConfig` 未逐行读,Part 06 要求「回退空档案 + 保留 .bak」并标【推断】。
|
||||
10. **`ScheduleDataGrid` 单元格渲染细节**(科目简称/颜色/换课标记的视觉)未细读,Part 06 标【推断】,视觉规格建议归入 Part 04/05 由 ui-island 统一。
|
||||
11. **`ProfileSettingsWindow.axaml` 的 2004 行中仅精读约 500 行**(结构、课表/时间表/临时/群/换课/导入导出区域)。剩余部分(约 900-1600 行为止的时间线列表模板、日程调整表格模板、附加设置项)只做了 outline 级 grep,像素细节若需要请 ui-island 或 windows part 补充。
|
||||
12. **接口文件 `ILessonsService` / `IProfileService` 未逐行读**:只依据实现类与调用点推断契约;对外接口方法名(如 `GetCyclePositionsByDate`、`CreateTempClassPlan`)已在 Part 06 使用实现类签名表述。
|
||||
13. **`ActionSetRunningControl` / `TriggerSettingsControl` / `ActionControl` / `RulesetControl` 的内部 UI 未精读**(仅确认存在与绑定方式),Part 08 只描述宿主页布局与行为契约;控件内部像素规格建议由 windows part 统一。
|
||||
14. **天气图标模板 / WeatherInfo 数据结构**(`ClassIsland.Core/Models/Weather`)未展开,Part 07 只用到 `Alerts[].Title/Detail/Type/PubTime/Images`、`ForecastDaily.Weather/SunRiseSet`、`Minutely.Precipitation.RainRemainingMinutes`、`Current.Weather`、`UpdateTime`。若需要完整天气数据 schema,需补读该目录(可能属 Part 05 天气组件范围)。
|
||||
15. **`GetSettingsDeltaTime` 的附加设置来源**:`ClassNotificationProvider` 使用 `IAttachedSettingsHostService`;附加设置体系(AttachedSettings)属跨 part 内容,Part 06/07 只按「按优先级取第一个启用项」描述,未定义完整附加设置模型,建议由 Lead 在总纲指定归属(可能在 Part 05 或 Part 13)。
|
||||
|
||||
## 3.1 裁决与修补(Lead 裁决,2026-11-12 修补轮)
|
||||
|
||||
本轮按 Lead 裁决修补 `parts/06`、`parts/07`、`parts/08`(不重写整篇),结论如下:
|
||||
|
||||
1. **Excel 导入/导出 = P1 必须实现**:用 `xlsx`(SheetJS)重建,禁止依赖 ReoGrid/WPF/OfficeOpenXml。ClassIsland 2.1 源码两个窗口整体 `#if false`,且 `ExcelImportViewModel`/`ExcelExportViewModel` 类型在仓库中**已不存在**(全仓检索无命中,属不可编译骨架),只能作布局参考。向导 UI 归 Part 11;Part 06 已新增 `6.9.1` 定义列格式、映射算法、往返一致性、预检规则与导出参数默认值(默认值标【推断】)。CSES 导入/导出标 **P0**。
|
||||
2. **ClearNotificationButtonWindow**:维持「不实现(`#if false` 遗留)」,清除提醒统一用右键菜单「清除全部提醒」→ `CancelAllNotifications`。
|
||||
3. **静音时段**:维持「ClassIsland 2.1 不存在、不得虚构」;可选扩展模型改为明确 **P2、默认关闭**,并要求命中时段时只屏蔽音效/语音/置顶/特效、不丢弃提醒。
|
||||
4. **NotificationPriority = 最终确定语义**:排序键 `(提供方优先级下标升序) → (Level: Emergency>High>Normal>Low) → (入队序号升序)`;新增 `NotificationLevel` 字段(默认 `Normal`);记录原比较器 `IsPriorityOverride` 取反的反常行为并声明按语义修正;旧字段兼容映射(读入 true→Emergency,写出 High/Emergency→true)。Part 07 §7.2 已删除互相矛盾的「逐位一致」表述。
|
||||
5. **附加设置 AttachedObjects = 2.x 现役机制**:`ClassIsland.Shared/AttachableSettingsObject.cs:15` 定义 `Dictionary<Guid, object?> AttachedObjects`;2.x `AttachedSettingsControlPresenter` 读取 `:241`、回写 `:361`。Part 06 新增 §6.10(定义/注册表 GUID/读取优先级/写回纪律/1.7 兼容/与档案分析关系/边界),Part 07 补全提醒侧的数据来源、GUID 与字段。**注意**:实际继承 `AttachableSettingsObject` 的是 `ClassPlan/ClassInfo/TimeLayout/TimeLayoutItem/Subject`;`Profile` 不继承(`Profile.cs:14`),故附加设置不能挂档案根——已在 §6.10.1 按源码写明。
|
||||
6. **天气服务**:Part 07 末尾新增 §7.14(刷新/缓存、定位与城市来源、完整 JSON schema、预警去重、图标主题、断网降级与重试、消费方分工、验收)。数据源证据为 `Services/WeatherService.cs` 全文、`ClassIsland.Core/Models/Weather/*` 全部 18 个模型、`IWeatherService`、`ILocationService`、`WeatherSettingsPage.axaml`、`Assets/XiaomiWeather/xiaomi_weather_status.json`。
|
||||
7. **其余未细读项**(Class Widgets 1.2 / ClassIsland 1.x 导入 helper 的字段映射、`ScheduleDataGrid` 单元格视觉)按要求**保持【推断】**,本轮不补读。
|
||||
8. 原 §3 第 3、4、14、15 条已被上述裁决覆盖/关闭;第 1 条已由裁决 4 关闭;第 5、8、9、10、11、12、13 条仍为开放缺口,保留原描述。
|
||||
|
||||
### 3.1.1 本轮补读文件清单(新增证据)
|
||||
|
||||
| 文件 | 用途 |
|
||||
|---|---|
|
||||
| `repos/ClassIsland/ClassIsland.Shared/AttachableSettingsObject.cs`(62 行) | `AttachedObjects` 字段 15、`GetAttachedObject` 23-32、写入 39-42、默认值重载 51-61 |
|
||||
| `repos/ClassIsland/ClassIsland.Shared/Interfaces/IAttachedSettings.cs`(40 行) | `IsAttachSettingsEnabled` 与 `GetIsEnabled`(含 JsonElement 兼容) |
|
||||
| `repos/ClassIsland/ClassIsland.Core/Abstractions/Services/IAttachedSettingsHostService.cs`(44 行) | 4 个注册集合(14-22)、`GetAttachedSettingsByPriority` 24-43 |
|
||||
| `repos/ClassIsland/ClassIsland/Services/AttachedSettingsHostService.cs`(13 行) | 实例侧集合 |
|
||||
| `repos/ClassIsland/ClassIsland.Core/Attributes/AttachedSettingsControlInfo.cs` / `AttachedSettingsUsage.cs` | 注册特性(GUID/名称/图标/hasEnabledState/targets) |
|
||||
| `repos/ClassIsland/ClassIsland.Core/Enums/AttachedSettingsTargets.cs` / `AttachedSettingsControlState.cs` | Flags 目标值、节点状态 Disabled/Enabled/Override |
|
||||
| `repos/ClassIsland/ClassIsland.Core/Controls/AttachedSettingsControlPresenter.axaml.cs`(421 行) | 读取 241、目标类型映射 245-253、状态提示 272-341、写回纪律 354-362 |
|
||||
| `repos/ClassIsland/ClassIsland/Helpers/AttachedSettingsControlHelper.cs`(69 行) | 控件侧读写 helper |
|
||||
| `repos/ClassIsland/ClassIsland/Controls/AttachedSettingsControls/*.axaml.cs`(4 个) | 4 个附加设置的 GUID/名称/图标/targets/hasEnabledState |
|
||||
| `repos/ClassIsland/ClassIsland/Models/AttachedSettings/{ClassNotification,AfterSchoolNotification,WeatherNotification}.cs`、`ClassIsland.Core/Models/AttachedSettings/LessonControlAttachedSettings.cs` | 附加设置模型与默认值 |
|
||||
| `repos/ClassIsland/ClassIsland/Models/AttachedSettingsNodeWithState.cs` | 节点+状态模型 |
|
||||
| `repos/ClassIsland/doc/AttachedSettings.md`(88 行) | 官方优先级说明 Subject→TimeLayoutItem→ClassPlan→TimeLayout(50-57) |
|
||||
| `repos/ClassIsland/ClassIsland.Core/Models/Weather/*.cs`(18 个,36+23+22+14+9+8+40+9+8+18+33+29+21+9+12+10+32 行) | 天气完整 schema 与派生字段 |
|
||||
| `repos/ClassIsland/ClassIsland.Core/Abstractions/Services/IWeatherService.cs`、`ClassIsland.Platforms.Abstractions/Services/ILocationService.cs` | 天气服务契约、定位契约 |
|
||||
| `repos/ClassIsland/ClassIsland/Views/SettingPages/WeatherSettingsPage.axaml`(327 行) | 城市搜索/位置设置/图标包/排除预警/不使用 TLS 的 UI 文案 |
|
||||
| `repos/ClassIsland/ClassIsland/Assets/XiaomiWeather/xiaomi_weather_status.json` | 天气码→中文文案表(0-35、53、301、302、99) |
|
||||
| `repos/ClassIsland/ClassIsland/Views/ExcelImportWindow.xaml.cs`(824 行,`#if false`) | 时间点解析正则/数字个数 422-458、自动补课间 502-522、科目 Contains 匹配 587-639、完成导入 695-708 |
|
||||
| `repos/ClassIsland/ClassIsland/Views/ExcelExportWindow.xaml.cs`(539 行,`#if false`) | 星期名 340-350、单元格生成 352-473、列宽/行高/边框 446-472、保存/打开 486-516 |
|
||||
|
||||
|
||||
|
||||
## 4. 与其他 part 的边界约定(避免重复/冲突)
|
||||
|
||||
- 窗口/控件像素级细节:主界面行、组件、主题样式以 Part 04/05/03 为准;本三篇只给与业务强相关的数值(气泡动画、斜切遮罩、特效窗口、课表窗口尺寸),并已注明来源,便于交叉核对。
|
||||
- 数据存储路径、备份、迁移、Settings/Profile JSON schema 总表:Part 13;本三篇给出的是业务字段语义与默认值,字段名保持一致(`Actions` 而非 `ActionItems`、`ClassPlans`、`OrderedSchedules` 等)。
|
||||
- 动画总表:Part 14;本三篇提供气泡/涟漪的时长与曲线原始值,建议 Part 14 直接引用本节,勿另行估算。
|
||||
- 设置中心页面树:Part 10;本三篇只描述「提醒」「自动化」两页的结构与文案,页面注册顺序由 Part 10 统一。
|
||||
- **Excel 导入/导出向导 UI 归 Part 11**;数据契约/列格式/往返一致性/预检以 Part 06 §6.9.1 为准,Part 11 只做步骤机与表单,不得另定格式。
|
||||
- **附加设置模型(AttachedObjects)以 Part 06 §6.10 为唯一事实源**;Part 05(组件)/Part 13(存储 schema)如需引用,必须沿用同名字段与同一优先级链,不得另立模型。
|
||||
- **天气服务与数据模型以 Part 07 §7.14 为准**;Part 05 的天气组件只消费 `LastWeatherInfo` 与 `SelectedWeatherIconTemplate`,不得自行请求或另定义 schema。
|
||||
- 提醒优先级语义(三级排序键 + `NotificationLevel`)以 Part 07 §7.2 为准,Part 08 的「显示提醒」行动与集控提醒都按此映射,不得各自定义顺序。
|
||||
@@ -0,0 +1,259 @@
|
||||
# analysis/island-ui.md —— ui-island 工作备注(Part 04 / 05)
|
||||
|
||||
- 任务:`task-2`(revision 2,owner: ui-island)
|
||||
- 产出:`parts/04-main-window.md`(CJK 6501 字)、`parts/05-components.md`(CJK 6982 字)
|
||||
- 工作方式:只读静态分析。未构建、未运行、未启动任何 UI/脚本、未截图、未安装依赖、未改动 `repos/`。
|
||||
|
||||
## 1. 已读文件清单
|
||||
|
||||
### 1.1 ClassIsland —— 主界面 / 行 / 主题 / 编辑模式
|
||||
|
||||
| 文件 | 读取范围 | 用途 |
|
||||
|---|---|---|
|
||||
| `analysis/00-brief.md` | 全文 | 团队总简报、格式与纪律 |
|
||||
| `repos/ClassIsland/ClassIsland/MainWindow.axaml` | 全文 686 行 | 窗口样式、根布局树、行模板、编辑 UI、原生菜单 |
|
||||
| `repos/ClassIsland/ClassIsland/MainWindow.axaml.cs` | 全文 1652 行 | 窗口几何、层级、点击穿透、编辑模式、菜单动作 |
|
||||
| `repos/ClassIsland/ClassIsland/ViewModels/MainViewModel.cs` | 全文 387 行 | `IsEditMode / ActualClientBound / ContainerComponents` 等 |
|
||||
| `repos/ClassIsland/ClassIsland/Controls/MainWindowLine.axaml` | 全文 79 行 | 行可见性表达式、`:dock-*` 伪类、行淡出 |
|
||||
| `repos/ClassIsland/ClassIsland/Controls/MainWindowLine.cs` | 全文 815 行 | 行模板部件、淡出判定、提醒队列、鼠标命中 |
|
||||
| `repos/ClassIsland/ClassIsland/XamlThemes/FluentTheme/Styles.axaml` | 全文 457 行 | 行背景/遮罩/浮层/进度条/动画参数(默认主题) |
|
||||
| `repos/ClassIsland/ClassIsland/XamlThemes/ClassicTheme/Styles.axaml` | 全文 375 行 | 经典主题的等价参数(TranslateY 遮罩) |
|
||||
| `repos/ClassIsland/ClassIsland.Core/Assists/MainWindowStylesAssist.cs` | 全文 | 6 个继承型附加属性(圆角/透明度/分体/编辑态等) |
|
||||
| `repos/ClassIsland/ClassIsland.Core/StylesBase.axaml` | 全文 | `Border.primaryColorZone`、`SettingsContainerWidth` 用法 |
|
||||
| `repos/ClassIsland/ClassIsland.Core/ThemeBase.axaml` | 1–90 行 | 字号资源 14/16/18/20、`SettingsContainerWidth=960`、图标字体 |
|
||||
| `repos/ClassIsland/ClassIsland.Core/Themes/WrapPanelResizingAnimation.axaml` | 全文 | `animated-resize` 类定义 |
|
||||
| `repos/ClassIsland/ClassIsland.Core/Themes/ComponentsPanelStyles.axaml` | 全文 | `components-panel` = 横排 StackPanel / 重排动画 |
|
||||
| `repos/ClassIsland/ClassIsland/Controls/EditMode/EditModeView.axaml` | 全文 613 行 | 抽屉、组件库、行设置、外观设置、配置管理 |
|
||||
| `repos/ClassIsland/ClassIsland/Controls/EditMode/EditModeView.axaml.cs` | 100–329 行 + grep | 抽屉打开/收起、容器组件、规则抽屉 |
|
||||
| `repos/ClassIsland/ClassIsland/Controls/EditMode/EditableComponentsListBox.axaml` | 全文 338 行 | 选中框、Adorner 操作条、拖拽阈值/预览/高亮 |
|
||||
| `repos/ClassIsland/ClassIsland/Controls/EditMode/EditModeContainerComponentInfo.cs` | 全文 | 浮动编辑框数据 |
|
||||
| `repos/ClassIsland/ClassIsland/Controls/SlantedMaskControl.cs` | 全文 346 行 | 斜面遮罩 5 区段权重/60°/360ms/120ms |
|
||||
| `repos/ClassIsland/ClassIsland.Core/Controls/VerticalDrawer.axaml` | 全文 157 行 | 抽屉外观、圆角 8 8 0 0、阴影、250ms |
|
||||
| `repos/ClassIsland/ClassIsland.Core/Controls/VerticalDrawer.axaml.cs` | 部分 + grep | `RequestedWidth`、`ContentHeightRatio=0.5` |
|
||||
| `repos/ClassIsland/ClassIsland.Core/Converters/SizeDoubleToCornerRadiusConverter.cs` | 全文 | 圆角 = 值/参数(1.0) |
|
||||
| `repos/ClassIsland/ClassIsland.Core/Converters/WidthDoubleToRectConverter.cs` | 全文 | 行裁切矩形 + 停靠位置 X 偏移 |
|
||||
| `repos/ClassIsland/platforms/ClassIsland.Platforms.Windows/Services/WindowPlatformService.cs` | 100–209 行 | `WS_EX_LAYERED/TRANSPARENT/NOACTIVATE`、Topmost/Bottommost/Private/ToolWindow |
|
||||
|
||||
### 1.2 ClassIsland —— 设置 / 数据模型
|
||||
|
||||
| 文件 | 读取范围 | 用途 |
|
||||
|---|---|---|
|
||||
| `repos/ClassIsland/ClassIsland/Models/Settings.cs` | 1–1856、1856–2255、grep 全文 | 全部主界面相关默认值(窗口/外观/组件/提醒/天气) |
|
||||
| `repos/ClassIsland/ClassIsland.Core/Models/Components/MainWindowLineSettings.cs` | 全文 | 行设置 21 个字段与默认值 |
|
||||
| `repos/ClassIsland/ClassIsland.Core/Models/Components/ComponentSettings.cs` | 全文 541 行 | 组件设置全部通用字段与默认值 |
|
||||
| `repos/ClassIsland/ClassIsland/Services/ComponentsService.cs` | 20–129 行 | 默认组件布局(1 行 = 日期 + 课程表)、配置文件路径 |
|
||||
| `repos/ClassIsland/ClassIsland/App.Services.xaml.cs` | 285–325 行 | Fluent 主题 `VerticalSafeAreaPx=20`、4 套天气图标模板 |
|
||||
| `repos/ClassIsland/ClassIsland/Services/XamlThemeService.cs` | 108–140 行 | `ActualVerticalSafeAreaPx` 取所有启用主题的最大值 |
|
||||
| `repos/ClassIsland/ClassIsland.Core/Models/XamlTheme/ThemeManifest.cs` | 110–132 行 + grep | `VerticalSafeAreaPx` 默认 0(Classic 主题即 0) |
|
||||
|
||||
### 1.3 ClassIsland —— 组件(全部 11 个)
|
||||
|
||||
| 文件 | 读取范围 |
|
||||
|---|---|
|
||||
| `Controls/Components/DateComponent.axaml` + `.axaml.cs` | 全文 |
|
||||
| `Controls/Components/ClockComponent.axaml` + `.axaml.cs` | 全文 |
|
||||
| `Controls/Components/CountDownComponent.axaml` + `.axaml.cs` | 全文(115 + 312 行) |
|
||||
| `Controls/Components/ScheduleComponent.axaml` + `.axaml.cs` | 全文(117 + 268 行) |
|
||||
| `Controls/Components/WeatherComponent.axaml` + `.axaml.cs` | 全文(314 行 + 68 行) |
|
||||
| `Controls/Components/TextComponent.axaml` + `.axaml.cs` | 全文 |
|
||||
| `Controls/Components/RollingComponent.axaml` + `.axaml.cs` | 全文(49 + 206 行) |
|
||||
| `Controls/Components/SlideComponent.axaml` + `.axaml.cs` | 全文(126 + 202 行) |
|
||||
| `Controls/Components/GroupComponent.axaml` + `.axaml.cs` | 全文 |
|
||||
| `Controls/Components/StackComponent.axaml` + `.axaml.cs` | 全文 |
|
||||
| `Controls/Components/SeparatorComponent.axaml` + `.axaml.cs` | 全文 |
|
||||
| `Controls/Components/*ComponentSettingsControl.axaml`(8 个) | grep 全部 `Header=/Content=/Minimum=/Maximum=/Description=` |
|
||||
| `Models/ComponentSettings/{Clock,CountDown,Group,Rolling,Slide,Stack,Text,Weather}ComponentSettings.cs` | 全文(grep 字段默认值) |
|
||||
| `Models/ComponentSettings/LessonControlSettings.cs` | 全文 189 行 |
|
||||
| `ClassIsland.Core/Controls/ComponentPresenter.axaml` | 全文 73 行(宿主通用行为) |
|
||||
| `ClassIsland.Core/Controls/ComponentAdvancedSettingsControl.axaml` | grep 全部设置项文案/范围 |
|
||||
| `ClassIsland.Core/Controls/LessonsControls/LessonsListBox.axaml` | 全文 204 行(课程列表容器与列表项主题) |
|
||||
| `ClassIsland.Core/Controls/LessonsControls/LessonControlExpanded.axaml` | 全文 240 行 |
|
||||
| `ClassIsland.Core/Controls/LessonsControls/LessonControlMinimized.axaml` | 全文 65 行 |
|
||||
| `ClassIsland.Core/Controls/LessonsControls/LessonControlSeperator.axaml` | 全文 27 行 |
|
||||
| `ClassIsland.Core/Controls/LessonsControls/LessonControlBase.cs` | 全文 75 行 |
|
||||
| `ClassIsland.Core/Controls/HighlightBox.axaml` | 全文 28 行 |
|
||||
| `Controls/WeatherIcons/{Index,SimpleTextWeatherIconTemplate}.axaml` | 全文(其余 3 套仅列名/大小) |
|
||||
|
||||
### 1.4 ClassHelper(实现栈参照)
|
||||
|
||||
| 文件 | 读取范围 | 用途 |
|
||||
|---|---|---|
|
||||
| `packages/shared/src/island-layout.ts` | 全文 404 行 | `CLASSISLAND_ISLAND_METRICS`(已核对与本任务一致)、组件契约、默认方案 |
|
||||
| `packages/shared/src/constants.ts` | 240–369 行 | `DEFAULT_ISLAND_APPEARANCE`、`ISLAND_SHADOW_PAD=10`、`ISLAND_SIZE_DELTA`、`ISLAND_TYPE_SCALE` |
|
||||
| `packages/desktop-client/src/main/island.ts` | 1–140、400–659 行 + grep | `BrowserWindow` 参数、`setIgnoreMouseEvents`、`setAlwaysOnTop('screen-saver')`、失焦宽限、固定包围盒、禁止 `setBackgroundMaterial` |
|
||||
| `packages/desktop-client/src/island/IslandApp.vue` | 200–399 行 + grep | 弹簧形变、`--island-*` 变量、`progress²` 交叉淡入、命中重算 |
|
||||
| `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/classic-island.css` | 全文 757 行 | 卡片/胶囊/列表排版系数与 token 命名 |
|
||||
| `packages/desktop-client/src/island/custom-island.css` | 全文 205 行 | 常驻行布局(`--custom-row-gap` 等) |
|
||||
| `packages/desktop-client/src/island/custom-runtime.css` | 全文 255 行 | 常驻卡片的 ClassIsland Fluent 化配色(`--wn-bg:#20202080`、`--wn-border:#ffffff26`) |
|
||||
| `packages/desktop-client/src/island/ComponentNode.vue` | 210–329 行 | 组件 DOM 类名约定(`component-node` + `node.kind`)、`tabular-nums` |
|
||||
| `repos/ClassIsland/AGENTS.md`、`repos/ClassHelper-master/AGENTS.md` | 注入全文 | 纪律约束 |
|
||||
|
||||
## 2. 关键参数表(数值 → 证据)
|
||||
|
||||
### 2.1 窗口与几何
|
||||
|
||||
| 参数 | 值 | 证据 |
|
||||
|---|---|---|
|
||||
| 窗口透明 | `Background=Transparent` / `TransparencyLevelHint=Transparent` / `TransparencyBackgroundFallback=Transparent` | `MainWindow.axaml:169-171, 33` |
|
||||
| 无边框 / 不可缩放 / 不可最大化最小化 | `SystemDecorations=None`, `CanResize=False`, `CanMaximize=False`, `CanMinimize=False` | `MainWindow.axaml:171-174` |
|
||||
| 不抢焦点 | `ShowActivated="False"` | `MainWindow.axaml:32` |
|
||||
| 初始高度 | `Height="1"` | `MainWindow.axaml:8` |
|
||||
| 编辑模式窗口底色 | `SmokeFillColorDefaultBrush` + `TransparencyLevelHint="AcrylicBlur, Transparent"` | `MainWindow.axaml:177-181` |
|
||||
| 自由窗口编辑模式 | `SystemDecorations=Full`、可缩放/最大化/最小化;Win10≤1803 用不透明底色 | `MainWindow.axaml:182-191`;`MainWindow.axaml.cs:257-260` |
|
||||
| 窗口标题 | `ClassIsland` / `编辑主界面 \| ClassIsland` | `MainWindow.axaml:175, 180` |
|
||||
| 自由窗口编辑模式屏幕边距 | `60` | `MainWindow.axaml.cs:134` |
|
||||
| 编辑模式窗口高 = 屏高 − 1px | 防 Windows 误判全屏 | `MainWindow.axaml.cs:970` |
|
||||
| 窗口宽度(非编辑) | `screen.Bounds.Width / dpiX`(整屏宽) | `MainWindow.axaml.cs:915` |
|
||||
| 窗口高度(非编辑) | `内容高 + safeT + safeB` | `MainWindow.axaml.cs:916` |
|
||||
| 竖直安全区 | Fluent `20` / Classic `0` | `App.Services.xaml.cs:314`;`ThemeManifest.cs:20` |
|
||||
| 停靠位置 6 值 + 默认 1 | `0..5`,默认中上 | `Models/Settings.cs:48, 1810-1823` |
|
||||
| 偏移 X/Y 默认 | `0` / `0`(物理像素) | `Models/Settings.cs:49-50` |
|
||||
| 显示器索引默认 | `0`,越界回退主屏 | `Models/Settings.cs:51`;`MainWindow.axaml.cs:806-812` |
|
||||
| 忽略工作区 | 默认 `false` | `Models/Settings.cs:1835` |
|
||||
| 窗口层级 | 默认 `1=置顶`;`0=置底` | `Models/Settings.cs:52, 1961-1978` |
|
||||
| 置顶重查模式 | 默认 `0`;另有 1/2/3(3=1ms 高频) | `Models/Settings.cs:1860`;`MainWindow.axaml.cs:136-139, 420-436` |
|
||||
| 任务栏显示条件 | `IsWindowMode \|\| IsScreenRecordingModeEnabled` | `MainWindow.axaml:34-39` |
|
||||
| 鼠标穿透(Windows) | `WS_EX_LAYERED \| WS_EX_TRANSPARENT \| WS_EX_NOACTIVATE` + `SetLayeredWindowAttributes` | `WindowPlatformService.cs:130-150` |
|
||||
| ToolWindow | 非编辑/非自由窗口/非录屏时启用 `WS_EX_TOOLWINDOW` | `MainWindow.axaml.cs:832-838`;`WindowPlatformService.cs:173-185` |
|
||||
| 防截屏 | `WDA_EXCLUDEFROMCAPTURE`,开关默认 `false` | `MainWindow.axaml.cs:840`;`Models/Settings.cs:1862` |
|
||||
| 提醒特效渲染缩放自动值 | 屏高 ≥1400 → 0.75;≥2000 → 0.5 | `MainWindow.axaml.cs:377-392` |
|
||||
|
||||
### 2.2 行(MainWindowLine)
|
||||
|
||||
| 参数 | 值 | 证据 |
|
||||
|---|---|---|
|
||||
| 行高 `IslandContainerHeight` | `40` | `MainWindowLine.axaml:16`、`FluentTheme/Styles.axaml:65`、`ClassicTheme/Styles.axaml:16` |
|
||||
| 内容盒内边距 / 最小宽 | `12 0` / `20` | `FluentTheme/Styles.axaml:109-110`、`ClassicTheme/Styles.axaml:99-100` |
|
||||
| 行间距默认 | `5`(范围 0–150,步进 5) | `Models/Settings.cs:219`;`MainWindow.axaml:344`;`EditModeView.axaml:114-120` |
|
||||
| 组件外边距 | `6 0`(相邻合计 12) | `MainWindow.axaml:396` |
|
||||
| 行背景圆角 | `RadiusX`(默认 8,0–20,步进 0.5) | `Models/Settings.cs:183, 1186-1196`;`SizeDoubleToCornerRadiusConverter.cs:8-17` |
|
||||
| 行背景边框 | `1px`,`ControlElevationBorderBrush` | `FluentTheme/Styles.axaml:46-47` |
|
||||
| 行背景阴影 | `0 4 8 2 #48000000` | `FluentTheme/Styles.axaml:49` |
|
||||
| 背景不透明度 | `Opacity` 默认 `0.5`(0–1,步进 0.05),只作用于背景层 | `Models/Settings.cs:64, 1140-1150`;`FluentTheme/Styles.axaml:44` |
|
||||
| 行不透明度 | 行级 `Opacity` 默认 `1.0`(0.1–1,步进 0.05) | `MainWindowLineSettings.cs:42`;`MainWindowLine.axaml:51` |
|
||||
| 行淡出不透明度 | `0.05` | `MainWindowLine.axaml:73-75` |
|
||||
| 行选择框 | `1.5px` 虚线、dash `1/1.5`、`opacity 0.75`、圆角端点、Bevel 连接 | `MainWindow.axaml:353-363` |
|
||||
| 行操作按钮间距/字号 | `2` / `14` | `MainWindow.axaml:403-406` |
|
||||
| 行过渡(Fluent) | `opacity 100ms`;`BackgroundWidth 300ms` `0.65,0,0.35,1.0` | `FluentTheme/Styles.axaml:264-273` |
|
||||
| 行过渡(Classic) | `opacity 100ms`;`BackgroundWidth 550ms` `0,1,0.5,1.10` | `ClassicTheme/Styles.axaml:202-211` |
|
||||
| 行挂载淡入 | `250ms` `0.25,1,0.5,1`,仅 `AnimationLevel≥2` | `MainWindowLine.cs:382-401`;`Models/Settings.cs:1851` |
|
||||
| 重排动画 | `300ms` `0.65,0,0.35,1.0` | `MainWindow.axaml:197-198` |
|
||||
| 分体主界面组件盒 | `Margin -2 0`、`MinWidth 40`、`ContentPresenter Margin 16 0` | `FluentTheme/Styles.axaml:245-259` |
|
||||
| 分体主界面开关 | 全局默认 `false`;行级 `IslandSeparationMode` 0/1/2 | `Models/Settings.cs:1852`;`MainWindowLineSettings.cs:47-50` |
|
||||
|
||||
### 2.3 遮罩 / 浮层 / 进度
|
||||
|
||||
| 参数 | 值 | 证据 |
|
||||
|---|---|---|
|
||||
| 遮罩斜面角度 | `60°`(`tan(30°)*h`,`SlantedHeight` 默认 80) | `SlantedMaskControl.cs:284-286, 25-26` |
|
||||
| 遮罩区段权重 | `[0, 0.1, 0.2, 0.4, 0.2, 0.1]`(5 段 + 首尾 0) | `SlantedMaskControl.cs:298-308` |
|
||||
| 遮罩区段时长 / 错峰 | `RegionDurationMs=360` / `StageStaggerMs=120`(行模板显式) | `FluentTheme/Styles.axaml:175-180` |
|
||||
| 打开错峰 | 0/4 → 0ms;1/3 → 90ms;2 → 120ms;`QuarticEaseOut` | `SlantedMaskControl.cs:177-188` |
|
||||
| 关闭错峰 | 2 → 0ms;1/3 → 90ms;0/4 → 120ms;`QuadraticEaseIn` | `SlantedMaskControl.cs:189-200` |
|
||||
| 遮罩文字淡入 | delay 260ms / 250ms / `0.25,1,0.5,1` | `FluentTheme/Styles.axaml:329-340` |
|
||||
| 遮罩文字缩放 | 1.1→1.0 / 750ms / delay 260ms | `FluentTheme/Styles.axaml:341-352` |
|
||||
| 强调底淡入 | delay 600ms / 100ms / Forward | `FluentTheme/Styles.axaml:355-367` |
|
||||
| 遮罩投影 | `0 8 32 0 #66000000` | `FluentTheme/Styles.axaml:323-328` |
|
||||
| 提醒进度条 | `Maximum=1`,`Value=LeftProgress`,过渡 50ms 线性 | `FluentTheme/Styles.axaml:131-146`;`MainWindowLine.axaml:77` |
|
||||
| 浮层淡入淡出 | 200ms `SineEaseIn` | `FluentTheme/Styles.axaml:419-451` |
|
||||
| Classic 遮罩 | `Y -50→0` 200ms `QuadraticEaseIn`;关 `Y 0→50` delay100ms 200ms `QuadraticEaseOut` | `ClassicTheme/Styles.axaml:265-318` |
|
||||
| Classic 首帧投影 | `DropShadowEffect` blur 8,`Effect` 过渡 100ms 线性 | `ClassicTheme/Styles.axaml:34-45` |
|
||||
| 进度精度降低 | 默认 `true`;`tick=max(10, totalSeconds/500)` | `Models/Settings.cs:1853`;`CountDownComponent.axaml.cs:291-295` |
|
||||
|
||||
### 2.4 编辑模式
|
||||
|
||||
| 参数 | 值 | 证据 |
|
||||
|---|---|---|
|
||||
| 底部操作栏 | `bottom 64px`、`CornerRadius 6`、`Padding 4`、按钮间距 `6`、`1px` 边框 | `MainWindow.axaml:595-604` |
|
||||
| 操作栏分隔线 | `0,0 → 0,25`、`1px` | `MainWindow.axaml:610-613` |
|
||||
| 抽屉宽度 | `960`(`SettingsContainerWidth`) | `ThemeBase.axaml:37`;`EditModeView.axaml:600-605` |
|
||||
| 抽屉圆角 / 阴影 | `8 8 0 0` / `0 8 32 0 #66000000` | `VerticalDrawer.axaml:9, 45` |
|
||||
| 抽屉内边距 / 标题栏 | `8 8 8 0` / 高 `32` | `VerticalDrawer.axaml:53-54` |
|
||||
| 抽屉过渡 | `bottom`+`height` 250ms `cubic-bezier(0,0,0,1)` | `VerticalDrawer.axaml:29-36` |
|
||||
| 次抽屉高度比例 | `0.5` | `EditModeView.axaml:608` |
|
||||
| 设置容器 | `Margin 12 12 18 12`、`Spacing 4` | `StylesBase.axaml:67-71` |
|
||||
| 组件库项 | 高 `50`、`Margin 0 8`、图标 `32`、描述 `12px/0.75`、WrapPanel 目标宽 `225` | `EditModeView.axaml:177-218` |
|
||||
| 拖拽阈值 / 预览透明度 | `3` / `0.5` | `EditableComponentsListBox.axaml:286-288` |
|
||||
| 拖拽插入高亮 | `1s` 交替无限,opacity `0.1↔0.6`,SineEaseInOut | `EditableComponentsListBox.axaml:307-336` |
|
||||
| 选中操作条 | `CornerRadius 6`、`Padding 4`、`Spacing 6`、`1px` 边框、分隔线高 25 | `EditableComponentsListBox.axaml:100-184` |
|
||||
| 容器组件浮动框 | `CornerRadius 6`、`Padding 4 0`、把手宽 20、列表高 40、初始 Y+48 | `MainWindow.axaml:485-537`;`MainWindow.axaml.cs:1559-1567` |
|
||||
| 隐藏组件斜条纹 | 45° 重复渐变 `#afffffff`/`#50ffffff` | `ComponentPresenter.axaml:20-33` |
|
||||
| 缩放 | `ZoomBorder` 0.5–3、speed 1.2、约束开启;设置 `Scale` 0.75–2.5 步进 0.05 | `MainWindow.axaml:199-212`;`EditModeView.axaml:50-57` |
|
||||
|
||||
### 2.5 组件(要点)
|
||||
|
||||
| 参数 | 值 | 证据 |
|
||||
|---|---|---|
|
||||
| 字号资源 | 14 / 16 / 18 / 20 | `ThemeBase.axaml:32-35`;`Models/Settings.cs:197-200` |
|
||||
| 默认字体 | `HarmonyOS Sans SC` + `FluentSystemIcons-Resizable` | `MainWindow.axaml.cs:185-189` |
|
||||
| 字重 | `FontWeight.Medium`(默认 500) | `Models/Settings.cs:101` |
|
||||
| 宿主内边距 | `0 8`(上下 8) | `ComponentPresenter.axaml:55-57` |
|
||||
| 组件宽约束默认 | min 100 / max 300 / fixed 200,全部关闭 | `ComponentSettings.cs:30-35, 37, 43` |
|
||||
| 组件不透明度默认 | `1.0` | `ComponentSettings.cs:46` |
|
||||
| 日期格式 | `ddd MM/dd` | `DateComponent.axaml:11` |
|
||||
| 时钟分隔符逻辑 | `!Flash \|\| ShowSeconds \|\| 秒%2==1` | `ClockComponent.axaml.cs:75` |
|
||||
| 倒计时环 | 22×22、描边 3.1、半径 `r=9.5`、>100% 按 99.9999 | `CountDownComponent.axaml.cs:34-47` |
|
||||
| 倒计时默认色/字号 | `#FFFF0000` / `16`(16–30) | `CountDownComponentSettings.cs`;设置页 `:410-414` |
|
||||
| 倒计时格式默认 | `%D天` | 同上 |
|
||||
| 课程列表高 | `40`、项 `MaxHeight 40` | `LessonsListBox.axaml:41, 107` |
|
||||
| 课程淡化 | `0.6`,`150ms` `CubicEaseInOut` | `LessonsListBox.axaml:56-77` |
|
||||
| 课程强调字号 | `18` + Bold | `LessonControlExpanded.axaml:66-67` |
|
||||
| 课程左右间隔 | `16px * ScheduleSpacing`(0.2–1) | `LessonControlExpanded.axaml:51-56, 219-224` |
|
||||
| 最小型间隔 | `10px * ScheduleSpacing` | `LessonControlMinimized.axaml:33-38` |
|
||||
| 高亮条 | 高 12、opacity 0.4、margin `-2 8 -2 0`、radius 2 | `HighlightBox.axaml:15-18` |
|
||||
| 天气主图尺寸 | 图标 22×22,图标右移 `-2px` | `WeatherComponent.axaml:42-44, 65-67` |
|
||||
| 预警药丸 | 高 22、radius 11、文本 `14px`、`margin 4 0 8 0` | `WeatherComponent.axaml:252-263` |
|
||||
| 降水药丸 | `padding 0 8`、`1px` 边框、底色 opacity 0.15、radius = 高/2 | `WeatherComponent.axaml:276-311` |
|
||||
| 滚动速度默认 | `40 px/s`(≥0.1) | `RollingComponentSettings.cs` |
|
||||
| 滚动暂停默认 | 启用、`10s`、偏移 `0` | 同上 |
|
||||
| 轮播间隔默认 | `15s`(≥0.1) | `SlideComponentSettings.cs` |
|
||||
| 轮播动画 | `250ms` `0.65,0,0.35,1`,位移 ±40 | `SlideComponent.axaml:72-107` |
|
||||
| 分割线 | `2×25`、`2px`、opacity 0.8 | `SeparatorComponent.axaml:10-13` |
|
||||
| 默认布局 | 1 行:日期 + 课程表 | `ComponentsService.cs:33-52` |
|
||||
|
||||
## 3. 未决问题 / 缺口(需要 Lead 或其它 part 决策)
|
||||
|
||||
1. **主题颜色 token 未取色**:`SolidBackgroundFillColorSecondaryBrush`、`ControlElevationBorderBrush`、`AccentFillColorDefaultBrush`、`SmokeFillColorDefaultBrush`、`CommandBarOverflowPresenterBackground/BorderBrush`、`ContentDialogBackground/BorderBrush/BorderWidth`、`AqiLevel1..6Brush` 的实际 HEX/alpha 未逐一定位取色(属 part 03 设计系统职责)。本 part 只写资源名与语义。**风险**:part 03 若用了不同命名,需要一次对齐。
|
||||
2. **ProgressBar 默认高度/圆角未确认**:FluentAvalonia 的 ProgressBar 模板高度直接影响行底提醒进度条、课程进度条、倒计时进度条的像素高度;part 04/05 已标【推断:约 3px】。需要 design 提供 token 或在实现里固定为 3px。
|
||||
3. **Acrylic 的 Electron 等价**:编辑模式用了 `TransparencyLevelHint="AcrylicBlur, Transparent"`。ClassHelper 的既有结论是禁止 `setBackgroundMaterial()`(会破坏逐像素透明)。本 part 给出的方案是"全屏半透明遮罩 + 窗口仍逐像素透明",**未验证视觉等价性**(不能运行)。需 Lead 决定是否接受该近似,或允许编辑模式例外使用材质。
|
||||
4. **`IsWindowMode` 的 UI 入口未定位**:`MainViewModel.EditModeIsWindowMode` 默认 `true`(`MainViewModel.cs:48`),但 `EditModeView.axaml` 中没有找到"全屏/自由窗口"切换按钮,可能在别的设置页或教程步骤里。属未决。
|
||||
5. **提醒在多行之间的分发策略**:`NotificationHostService.RegisterNotificationConsumer(this, IsMainLine ? -1 : LineNumber)`(`MainWindowLine.cs:441`)只说明注册顺序,具体"多行都启用提醒时谁显示"的规则在 `NotificationHostService` 内部,本 part 未深入(属 part 07)。
|
||||
6. **`StackComponent` 的测量语义**:Avalonia `Panel` 中带 `Margin="6 0"` 的子项,其宽度是否计入容器测量宽,未验证;实现时以实测为准(本 part 按"取子项最大宽度 + 6px 外边距"描述)。
|
||||
7. **`ZoomBorder` 手势细节**:`ZoomBorder` 未定位到源码(可能来自 Avalonia 扩展库),滚轮是否需修饰键、双击是否重置、平移边界计算均为【推断】,已在 part 04 §4.6 标注。
|
||||
8. **`TextComponent` 字号与全局字号的关系**:文本组件用自身 `Settings.FontSize`(默认 16),不随 `MainWindowBodyFontSize` 变化,除非开启资源覆盖。这是源码事实,但产品上可能造成困惑,建议 part 10(设置中心)或 part 16 提示。
|
||||
9. **斜面遮罩的完整 CSS**:part 04 只给了 5 段权重、60°、时长、缓动与实现思路,未给可直接粘贴的完整 `@keyframes` + 5 个 `clip-path` 片段(篇幅取舍)。若 Lead 要求"可直接粘贴",需补一节。
|
||||
10. **窗口高度=内容高的方案取舍**:ClassIsland 是"窗口随内容高变化",ClassHelper 是"固定包围盒 + 窗内形变"。part 04 按 ClassIsland 写(附 ClassHelper 参考),但两者在"展开/折叠"场景下动画观感不同;需要 Lead 在 part 01/14 统一口径。
|
||||
11. **`MainWindow.axaml:8 Height="1"`** 的初始化意图未深究(Electron 无对应需求)。
|
||||
12. **`ReduceProgressAccuracy` 对主界面行提醒进度条的量化**:源码只对倒计时组件做了量化(`CountDownComponent.axaml.cs:291-295`),行进度条是否也量化未直接看到;part 04 §4.7.1 写成"同样应做降频"属【推断】。
|
||||
13. **`ExtraInfo4ShowSecondsSeconds`、`ShowTomorrowSchedules`、`PauseOnRule`/`PauseRule`(滚动容器)** 等字段在源码中存在但当前 UI 未暴露或未使用,属历史/预留字段;part 05 已标注"保留/兼容",实现时可保留 JSON 字段但不提供 UI。
|
||||
14. **多显示器 `WindowDockingMonitorIndex` 与 DPI 混合场景**:ClassIsland 用所选屏幕的 `Scaling` 统一换算,若显示器 DPI 不同,跨屏拖动时会重算;part 04 只写了公式,跨 DPI 拖动的边界行为未验证。
|
||||
15. **`WindowTopmostRecheckMode` 的 1ms 高频模式**(`WindowTopmostRecheckMode==3`)在 Electron 下不可照搬(1ms 轮询会烧 CPU),part 04 已建议最小 1000ms;需 Lead 在 part 18(禁止事项/性能底线)确认。
|
||||
|
||||
## 4. Lead 裁决回填(第二轮,已完成)
|
||||
|
||||
Lead 对 §3 未决项做了最终裁决,已按"小范围修补"回填 parts 04/05(未重写整篇):
|
||||
|
||||
| # | 裁决 | 回填位置 |
|
||||
|---|---|---|
|
||||
| 1 | **禁止**系统材质 API;编辑态用 `rgba(0,0,0,0.30)` 全屏遮罩 + 逐像素透明,**禁 `backdrop-filter`**;标【推断/差异说明】,不得写"与 Acrylic 完全一致" | 04 §4.8.1、验收 14;拖拽预览浮标降级色 §4.8.8 |
|
||||
| 2 | 窗口改采**固定包围盒 + 窗内形变**:宽 = 屏宽,高 = `contentMaxHeight + 2*safePadding`,`setBounds` 节流 ≥100ms;编辑模式扩展为「屏宽 ×(屏高−1px)」+ 四边 60px 安全边距 + 开鼠标;保留 ClassIsland 视觉结果(可见岛高 = 行高之和 + 行距) | 04 §4.1 约定 1、§4.3 全节重写(4.3.1 裁决 / 4.3.2 视觉基准 / 4.3.3 编辑画布 / 4.3.4 节流)、§4.6、§4.8.2、§4.9、验收 5/5.1/6/14 |
|
||||
| 3 | 进度条高度**定为 3px**(`--ci-progress-height`),3 处【推断≈3px】改确定值 | 04 §4.4 token 表 + §4.7.1 + 验收 8.1;05 §5.4、§5.5.2、§5.15 |
|
||||
| 4 | `IsWindowMode` 不实现 UI 入口,保留字段与能力说明,标 **P2/【推断】**;注明 2.1 中该设置存在但编辑页无可见切换按钮 | 04 §4.2 第 5 条 |
|
||||
| 5 | 置顶:事件驱动 + 兜底轮询 **≥1000ms**,**禁止 1ms/10ms 级轮询**,另列各模块刷新频率 | 04 §4.2 第 4 条 + 新增 §4.2.1 性能底线 + 验收 5.1 |
|
||||
| 6 | ZoomBorder:**仅 `Ctrl+滚轮` 0.5–3.0 + 双击重置**;不做平移(`Space+drag` 标 P2/【推断】) | 04 §4.6 全节重写 |
|
||||
| 7 | 提醒多行分发规则归 part 07;04 只保留宿主与 `IsNotificationEnabled` 标记 | 04 §4.5.8、验收 8 |
|
||||
| 8 | 预留 JSON 字段保留 schema、不给 UI,统一标【预留】 | 05 §5.5.5、§5.8、§5.9(含统一处置说明) |
|
||||
|
||||
修补后字数:04 = CJK 8360(+1859)、05 = CJK 7173(+191)。仍为只读分析、未运行任何程序、未改 `repos/`。
|
||||
|
||||
## 5. 自检
|
||||
|
||||
- [x] 数值全部有 `路径:行号` 证据或标【推断】。
|
||||
- [x] 覆盖 `MainWindow.axaml(.cs)`、`MainWindowLine`、两套主题 Styles、全部 11 个组件 axaml+cs、8 个组件设置控件、EditMode 三个文件、ComponentPresenter、LessonsListBox + 3 种课程控件、SlantedMaskControl、VerticalDrawer、两个关键 Converter、Windows 平台窗口特性实现。
|
||||
- [x] 覆盖 ClassHelper 侧 island.ts / IslandApp.vue / spring.ts / squircle.ts / classic-island.css / custom-island.css / custom-runtime.css / ComponentNode.vue / shared island-layout.ts + constants.ts。
|
||||
- [x] 两份 part 均含「验收标准」小节,且均为中文祈使句、无"建议考虑"式模糊表述。
|
||||
- [x] CJK 字数:04 = 8360,05 = 7173(要求 ≥5000)。
|
||||
- [x] Lead 8 条裁决已全部回填(见 §4)。
|
||||
- [x] 未构建、未运行、未截图、未安装依赖、未修改 `repos/`。
|
||||
@@ -0,0 +1,136 @@
|
||||
# ClassHelper 灵动岛重构调研笔记(Part 02/04/05 支撑)
|
||||
|
||||
> 本文件是队友 `stack` 在 Round 2 的静态分析记录,供 Lead 汇总审校时核对"读了什么、依据哪一行、还剩什么没定"。
|
||||
> 全程只用 read/grep/glob 与纯文本统计命令;**未构建、未安装、未运行 Electron、未截图、未冒烟/verify**;未修改 `repos/` 下任何文件。
|
||||
|
||||
## 1. 已读文件清单(Round 2)
|
||||
|
||||
### 1.1 ClassHelper(`repos/ClassHelper-master`,全部为只读)
|
||||
|
||||
| 文件 | 行数 | 本轮用途 |
|
||||
|---|---|---|
|
||||
| `docs/app/island.md` | 79 | 产品口径:fixed/custom、消息展示矩阵、编辑器、课程与课件、验证纪律 |
|
||||
| `docs/dev/implementation.md` | 54 | 实现契约:方案存 `config.json.islandLayout`、单窗口、编辑页子路由 |
|
||||
| `docs/dev/winisland-design-tokens.md` | 59 | 几何/度量/动画入口(已在上一轮读过,本轮复核) |
|
||||
| `docs/dev/testing.md` | 79 | 验证命令与"默认无头、--visual 才做桌面验收"纪律 |
|
||||
| `packages/shared/src/types.ts`(1050-1230 等片段) | 1874 总 | `IslandMode/IslandNotificationKind/IslandLessonReminder/IslandNotification/IslandAppearance/IslandState`、`ScheduleDto`、`WeekParity` |
|
||||
| `packages/shared/src/island-layout.ts` | 404 | 组件枚举、`CLASSISLAND_ISLAND_METRICS`、方案/行/节点 schema、默认值、`normalizeIslandLayouts` |
|
||||
| `packages/shared/src/constants.ts`(多段) | 680 总 | `DEFAULT_ISLAND_APPEARANCE`、范围、停靠、风格、`ISLAND_SIZE_DELTA`、`SHADOW_PAD`、`ISLAND_TYPE_SCALE`、`ISLAND_LIST_METRICS`、`PRIORITY_RANK/LABELS`、`CLIENT_UPDATE_IDLE_MS` |
|
||||
| `packages/shared/src/class-plan.ts`(1-100) | 119 | `TIME_POINT_TYPES`、`IslandTimePointDto`、`ActiveClassPlanWeekDto` |
|
||||
| `packages/shared/src/courseware.ts`(grep) | — | `COURSEWARE_ISLAND_SIZE={424,132}` |
|
||||
| `src/core?: packages/desktop-client/src/island/main.ts` | 30 | 岛渲染入口、二次注入动效令牌 |
|
||||
| `src/island/LayoutIslandApp.vue` | 76 | 布局选择/课件覆盖/订阅初始化 |
|
||||
| `src/island/IslandApp.vue` | 683 | 经典岛全部逻辑(弹簧、圆角、胶囊、展开、命中、停靠、内容淡入) |
|
||||
| `src/island/CustomIslandRuntime.vue` | 528 | 自定义常驻:测量/三页淡入/铃铛/行渲染/命中 |
|
||||
| `src/island/ComponentNode.vue` | 456 | 14 类组件渲染、课程表折叠、进度/徽标、编辑手柄、样式 |
|
||||
| `src/island/IslandEditorNode.vue` | 124 | 编辑器标签节点 + 拖拽落点样式(属 `renderer/components`) |
|
||||
| `src/island/ClassicNotifications.vue` | 234 | 单条详情卡/多条列表卡/按钮行 |
|
||||
| `src/island/LessonReminderContent.vue` | 318 | 课程提醒条、5 区斜切遮罩、进度条、徽标 |
|
||||
| `src/island/CoursewareTransfer.vue` | 132 | 课件传输覆盖卡(尺寸/样式/进度) |
|
||||
| `src/island/WeatherBrief.vue` | 91 | 天气简报组件与码表映射 |
|
||||
| `src/island/spring.ts` / `squircle.ts` | 115 / 81 | 弹簧参数、连续圆角路径 |
|
||||
| `src/island/classic-island.css` | 757 | 经典岛根变量、形状/投影、胶囊/展开/列表/按钮/状态色 |
|
||||
| `src/island/custom-island.css` / `custom-runtime.css` / `lesson-ending.css` | 205 / 255 / 16 | 自定义组件样式、常驻三页样式、秒数徽标 |
|
||||
| `src/main/island.ts` | 2445 | 主进程岛控制器全文(分区间阅读 + 末段 IPC/尺寸函数) |
|
||||
| `src/main/lesson-reminder.ts` | 110 | 五类课程提醒计算 |
|
||||
| `src/main/island-weather.ts` | 73 | Open-Meteo 抓取/缓存/退避 |
|
||||
| `src/main/index.ts`(岛相关) | 347 总 | 启动装配、岛初始化、打开应用/编辑器/已读回调、退出清理 |
|
||||
| `src/main/tray.ts`(岛相关) | 78 | 托盘"编辑灵动岛布局"入口 |
|
||||
| `src/main/courseware.ts`(grep) | — | `island.setCoursewareTransfer(value)` |
|
||||
| `src/preload/island.ts` | 123 | 岛窗口 contextBridge 白名单 |
|
||||
| `src/preload/index.ts` | 101 | 主窗口桥(含 island push/class state/mark-read 订阅) |
|
||||
| `src/renderer/island/bridge.ts` | 473 | 课表/上课状态/通知/作业/叫人/补弹/已读/生命周期 |
|
||||
| `src/renderer/views/settings/IslandSettingsView.vue` | 512 | 设置页脚本 + 模板结构(family 入口需新增) |
|
||||
| `src/renderer/views/settings/IslandEditorView.vue`(多段) | 861 | 编辑器:保存队列/上限/方案/拖拽/应用/加载 |
|
||||
| `src/renderer/components/IslandComponentSettings.vue` | 307 | 内容/外观/高级三页字段 |
|
||||
| `src/renderer/components/IslandEditorNode.vue` | 124 | 编辑器节点 chip/容器/落点 |
|
||||
| `src/renderer/styles/island-editor.css`(选择器) | 417 | 编辑器布局/预览画布/组件库/检查器样式 |
|
||||
| `src/renderer/styles/index.css`(grep 关键字) | 892 总 | 与岛相关的全局 token(未逐行引用) |
|
||||
| `src/types/desktop.d.ts` | 294 | 桥接契约与配置形状(上一轮已读,本轮复核 island 部分) |
|
||||
| `src/main/config.ts` | 555 | `islandLayout/island` 归一化、合并写、退出 flush(迁移接入点) |
|
||||
| `src/renderer/App.vue` / `layouts/ClientLayout.vue`(岛相关) | — | 桥接生命周期、编辑页路由入口 |
|
||||
| `AGENTS.md`(自动注入) | — | §4 灵动岛硬约束、验证纪律 |
|
||||
|
||||
### 1.2 ClassIsland(本轮仅少量回查,复用上一轮 parts)
|
||||
|
||||
- 上一轮产出的 `parts/03,04,05,07,10,11,14` 与 `analysis/40-baseline.md`(Lead 已整理),本轮引用其行高 40/行距 5/圆角 8/字号 14/16/18/20/进度条 3px/斜切遮罩权重等规格。
|
||||
- 直接回查:`repos/ClassIsland/ClassIsland.Core/Models/Components/MainWindowLineSettings.cs`(行隐藏规则语义)、`ClassIsland.Shared/Models/Profile/TimeLayoutItem.cs:119-138`(TimeType 0-3)、`ClassIsland.Core/Models/Notification/NotificationRequest.cs:14-20`(Mask/Overlay 5s 默认)。
|
||||
|
||||
### 1.3 团队上下文
|
||||
|
||||
- `analysis/50-refactor-brief.md`(Round 2 总简报,含 8 条裁决与 §2.3 的 family/fixed 补充口径)
|
||||
- 共享任务 `task-6`(已认领/完成)
|
||||
- 上一轮本人产出:`parts/02-tech-stack.md`、`parts/12-plugins-ipc.md`、`parts/13-data-storage.md`、`analysis/classhelper-stack.md`(仅作技术栈与工程约定参考)
|
||||
|
||||
## 2. 关键行号表(本轮引用最频繁,供 Lead 复核)
|
||||
|
||||
| 主题 | 文件:行 | 事实 |
|
||||
|---|---|---|
|
||||
| 岛窗口创建 | `src/main/island.ts:480-512` | 透明/无边框/置顶/不占任务栏/独立 preload/sandbox |
|
||||
| 窗口导航白名单 | `src/main/island.ts:32-50,516-522` | 生产按精确 file URL、拒绝新开窗口 |
|
||||
| 默认鼠标穿透 | `src/main/island.ts:527` | `setIgnoreMouseEvents(true,{forward:true})` |
|
||||
| 固定包围盒 | `src/main/island.ts:1514-1648` | `windowBox/windowBounds`,触摸贴合、自定义夹取 |
|
||||
| 尺寸基线/增量 | `src/main/island.ts:72-112`、`packages/shared/src/constants.ts:344-351` | 胶囊 216×34;展开/紧急/叫人增量 |
|
||||
| 收回动画 | `src/main/island.ts:1106-1164` | `CLOSE_ANIMATION_MS=360`,先切胶囊再淡出 |
|
||||
| 超时表 | `src/main/island.ts:121-132` | pill 15s/展开 20s/紧急 45s/叫人 90s 等 |
|
||||
| 消息分流 | `src/main/island.ts:794-867` | 紧急立即、上课暂存、普通叫人可点、预览展开 |
|
||||
| 上课态迁移/课后补弹 | `src/main/island.ts:870-927` | 进入上课隐藏、下课恢复/补弹 |
|
||||
| 动作状态机 | `src/main/island.ts:929-1077` | expand/collapse/expand-list/dismiss(-all)/mark-read(-all)/open-app |
|
||||
| 双播合并 | `src/main/island.ts:704-724` | 同 id 合并,call/URGENT 不被降级 |
|
||||
| 列表布局 | `src/main/island.ts:755-765`、`packages/shared/src/constants.ts:379-471` | 默认 3 行、hint more/app、safetyPad 6 |
|
||||
| 命中轮询 | `src/main/island.ts:2049-2078` | 60ms 读光标,先换屏再命中 |
|
||||
| 命中开关 | `src/main/island.ts:1795-1822` | 只由主进程关闭;触摸/编辑/自定义强制 true |
|
||||
| 岛体矩形 | `src/main/island.ts:1825-1836,1973-1997` | 渲染上报 50ms 限流;兜底 expectedHitRect |
|
||||
| 失焦宽限 | `src/main/island.ts:557-578,2287-2297` | 指针在岛上不收起;鼠标 500ms/触摸 1200ms |
|
||||
| 触摸模式 | `src/main/island.ts:245-316,1891-1902` | 贴合岛体+始终接收输入;setShape 仅 win32 |
|
||||
| 窗口自愈 | `src/main/island.ts:2106-2152` | 心跳 20s 超时、10 分钟最多 3 次 |
|
||||
| 外观归一化 | `src/main/island.ts:2225-2264` | 夹取+NaN fallback;范围与 shared 一致 |
|
||||
| IPC 注册 | `src/main/island.ts:2338-2438` | 全部 `island:*` handler 与发送方校验 |
|
||||
| 渲染桥 | `src/preload/island.ts:14-121` | `window.island` 白名单 |
|
||||
| 数据桥 | `src/renderer/island/bridge.ts:148-172,416-473` | 每秒复算上课态、课表刷新、生命周期 |
|
||||
| 经典渲染 | `src/island/IslandApp.vue:188-212,266-332,346-383,420-516` | 目标尺寸/圆角、弹簧帧循环、透明度、命中上报 |
|
||||
| 自定义渲染 | `src/island/CustomIslandRuntime.vue:52-124,238-323` | 测量/适配/三页淡入/命中 |
|
||||
| 组件渲染 | `src/island/ComponentNode.vue:29-210,212-293,294-454` | 折叠规则/条件渲染/组件样式 |
|
||||
| 消息面板 | `src/island/ClassicNotifications.vue:104-233` | 列表/详情/按钮语义 |
|
||||
| 课程提醒条 | `src/island/LessonReminderContent.vue:59-123,195-317` | 5 区遮罩 360ms/错峰、文字 260/250/750ms |
|
||||
| 课程提醒算法 | `src/main/lesson-reminder.ts:14-110` | 五类提醒窗口与 mask/ends 计算 |
|
||||
| 天气 | `src/main/island-weather.ts:1-73` | Open-Meteo、8s、64KB、15min 缓存、退避 |
|
||||
| 课件覆盖 | `src/main/island.ts:661-676,1420-1429`、`CoursewareTransfer.vue:12-65` | 最高优先级覆盖;424×132 |
|
||||
| 配置读写 | `src/main/config.ts:26-84,198-233,235-346` | 默认值/归一化/合并写/flush |
|
||||
| 布局 schema | `packages/shared/src/island-layout.ts:3-158,256-403` | 组件枚举/方案/行/节点/归一化上限 |
|
||||
| 度量常量 | `packages/shared/src/island-layout.ts:19-36` | ClassIsland:40/12/8/0.5/14-20/5/0.05 |
|
||||
| 消息常量 | `packages/shared/src/constants.ts:183-209,344-402` | 优先级、尺寸增量、排版系数、列表度量 |
|
||||
| 设置页 | `src/renderer/views/settings/IslandSettingsView.vue:26-160` | 外观/布局/预览逻辑 |
|
||||
| 编辑器 | `src/renderer/views/settings/IslandEditorView.vue:81-105,290-337,338-540` | 保存队列/应用/拖拽/上限 |
|
||||
| 组件设置 | `src/renderer/components/IslandComponentSettings.vue:26-307` | 内容/外观/高级字段与范围 |
|
||||
|
||||
## 3. 与 Lead 口径的对齐(family / fixed 重新定义)
|
||||
|
||||
Lead 补充口径已并入 04/05:
|
||||
|
||||
1. `appearance.family: 'classisland' | 'winisland'` 新增,**新装默认 classisland**;**老用户升级默认 winisland**。落点:04 §4.0 第 5-6 条、§4.2 表、§4.3.1/4.3.2/4.3.3/4.3.4;05 §5.2/§5.4。
|
||||
2. `fixed` 重新定义:classisland 下 fixed = ClassIsland 风格信息行(默认 1 行 = 日期 + 课程表、行高 40、圆角 8、不透明度 0.5、3px 进度条、消息行内气泡);原胶囊+详情卡只在 winisland 保留。落点:04 §4.3.2/4.3.3/4.3.4、05 §5.3 `FixedSchemeV2`。
|
||||
3. 文件级改造已覆盖 `IslandApp.vue` 的大改:迁为 `family/winisland/ClassicIsland.vue`(winisland 行为不变),新增 `family/classisland/FixedInfoRow.vue` + `InlineMessageBubble.vue`,`LayoutIslandApp.vue` 四象限分发;`ClassicNotifications.vue` → `shell/MessagePanel.vue`(detail/list/inline 三形态),`LessonReminderContent.vue` → `shell/LessonBar.vue`。
|
||||
4. 老 `style(black/glass/tinted)` 处理为兼容字段:新 canonical 字段 `appearance.winislandStyle`,读入优先新字段、回退旧字段,写出保留旧字段一个版本周期(05 §5.2/§5.10),避免旧配置文件解析断裂。
|
||||
|
||||
## 4. 未决项(需 Lead 或对应 part 拍板)
|
||||
|
||||
1. **fixed 信息行的默认行数与内容**:我按"1 行 = 日期 + 课程表"写入 05;03/07 若无异议需保持一致。是否允许默认再加"当前课程进度/倒计时"由 07 定。
|
||||
2. **消息行内气泡的交互细节**:行内气泡点击后是"展开行内详情"还是"打开应用通知中心",以及多条气泡叠放/横向滚动规则,属 07/08 范围;04 只规定"业务状态机不变,只换表现"。
|
||||
3. **classisland 的 Fluent/Classic 主题映射**:04 用 `appearance.theme: 'fluent'|'classic'` 占位;具体颜色/圆角/阴影 token 归 06/03,需确认是否与 ClassIsland XAML 资源字典逐值对应。
|
||||
4. **行设置抽屉字段清单**:04/05 定义了行级 appearance/hideRules/progress 的最小集;抽屉的完整分组与控件归 09,需与 05 schema 对齐后再定稿。
|
||||
5. **`style` 字段的移除时间**:建议 v3 移除;若 Lead 要求长期保留则改为永久兼容字段。
|
||||
6. **smoke 断言改造归属**:现状大量断言依赖旧 DOM/几何(如"固定包围盒全程不变");本轮未改 smoke,改造清单只列"需按 family 分套",具体断言列表需 Lead 安排给验收负责人或在 11 部分细化。
|
||||
7. **自定义方案在 winisland family 下的视觉**:04 §4.3.1 规定 custom 共用一套运行时、由 family 切样式变量;若希望 winisland 下有独立 custom 外观,需要再拆一套 CSS(当前判断为不必要)。
|
||||
8. **classisland 信息行与"课程提醒"的叠加方式**:我规定提醒条作为行覆盖层出现、不替换常态行(02 §2.8 现状语义);07/08 若希望"提醒整行替换"需同步 05 的 fixed metrics。
|
||||
9. **天气组件是否保留 Open-Meteo**:本轮只做岛重构,天气继续用现状实现(02 §2.9);ClassIsland 天气服务仅作语义参考,不引入其服务端数据模型。
|
||||
10. **`schemaVersion` 与 `islandLayout.version` 的关系**:我定义为文件级 + 子结构级双版本;若 Lead 希望只保留一个版本号,需同步修改 05 §5.1 与 04 §4.3.12。
|
||||
11. **编辑器 855 行拆分节奏**:04 要求先抽 composables 再改逻辑;若本轮排期紧,允许先抽 `useIslandDraft`,其余留到 M7。
|
||||
12. **family 切换是否自动写 `winislandStyle`**:当前迁移会写;新装用户从 classisland 切到 winisland 时是否保留 `black` 默认由 09 的 UI 决定。
|
||||
|
||||
## 5. 静态分析纪律声明
|
||||
|
||||
- 全程只读:`read` 读文本、`grep`/`glob` 找文件、`Select-String`/`Get-Content` 做文本统计与结构梳理、`[regex]` 统计中文字符数。
|
||||
- 未执行 `pnpm install/dev/build`、`electron`、`npm`、`verify:*`、截图、冒烟或任何会弹窗/占用屏幕的命令。
|
||||
- 未修改 `repos/ClassIsland` 与 `repos/ClassHelper-master` 下任何文件;只写入了 `parts-r/02-current-state.md`、`parts-r/04-file-plan.md`、`parts-r/05-data-migration.md`、`analysis/refactor-current-state.md`。
|
||||
- 证据标注口径:`packages/...:行号`(ClassHelper)与 `repos/ClassIsland/...:行号`;无法从源码直接确认的工程设计一律标【推断】。
|
||||
@@ -0,0 +1,94 @@
|
||||
# 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 确认。
|
||||
@@ -0,0 +1,140 @@
|
||||
# refactor-messages(Round 2 · Part 03/08)分析备注
|
||||
|
||||
负责人:features。产出:`parts-r/03-classisland-baseline.md`、`parts-r/08-messages-lessons.md`。
|
||||
本文件记录:已读文件清单、口径与默认值表、裁决落点、未决问题。全部为静态阅读,未构建/运行/启动 Electron/截图,未修改 `repos/`。
|
||||
|
||||
## 0. 口径(Lead 最新补充,已落到文档)
|
||||
|
||||
- 默认风格 `appearance.family='classisland'`:`fixed` **重定义为 ClassIsland 风格信息行**(默认 1 行 = 日期 + 课程表;行高 40、圆角 8、背景不透明度 0.5、底部 3px 进度条;消息到来在同一行内展开 ClassIsland 气泡,保留 ClassHelper 暂存/紧急/叫人/已读/去重规则)。
|
||||
- `family='winisland'`:保留原「胶囊 + 详情卡」形态;**老用户升级默认 winisland,新安装默认 classisland**。
|
||||
- `custom`:保留 schemes/rows/nodes 模型,按 ClassIsland 行/组件/编辑/隐藏/动画规格重构。
|
||||
- 落盘字段名以 `parts-r/05` 为准;本文档统一写作 `appearance.family`(配置键 `islandAppearance.style`)。
|
||||
|
||||
## 1. 已读文件清单
|
||||
|
||||
### 1.1 ClassHelper 文档
|
||||
|
||||
| 文件 | 关键内容 |
|
||||
|---|---|
|
||||
| `repos/ClassHelper-master/docs/app/island.md`(79 行) | 两种模式展示矩阵(8-24)、编辑自定义方案(36-48)、外观/位置/输入(50-59)、课程与课件(61-73)、验证纪律(75-79) |
|
||||
| `repos/ClassHelper-master/docs/app/notifications.md`(50 行) | 优先级四档(13-14)、两模式展示表(16-22)、紧急 45s 收起(23)、课堂紧急通知服务端 409(25-29)、已读/撤回(31-35)、接口表(37-49) |
|
||||
| `repos/ClassHelper-master/docs/app/courseware.md`(46 行) | 512MB 上限、可见范围/推送、客户端自动下载与 SHA256 回执、断网缓存、归档路径、服务端归档 |
|
||||
| `repos/ClassHelper-master/docs/dev/winisland-design-tokens.md`(59 行) | 经典几何(268×44、圆角 20、字号 13、边距 8)、`CLASSISLAND_ISLAND_METRICS` 汇总(30-42)、弹簧参数(46-47)、命中与触摸(51-53) |
|
||||
|
||||
### 1.2 shared 契约与常量
|
||||
|
||||
| 文件 | 关键内容 |
|
||||
|---|---|
|
||||
| `packages/shared/src/types.ts` | `NotificationPriority`(30)、`ScheduleDto`(545-564)、`IslandMode`(1103)、`IslandNotificationKind`(1111)、`IslandLessonReminder`(1114-1128)、`IslandNotification`(1131-1143)、`IslandAppearance`(1146-1188)、`IslandState`(1198-1230) |
|
||||
| `packages/shared/src/constants.ts` | `PRIORITY_LABELS/TAG_TYPES/RANK`(181-208)、`DEFAULT_ISLAND_APPEARANCE`(265-290)、`ISLAND_APPEARANCE_RANGES`(293-302)、`ISLAND_POSITIONS`(305-312)、`ISLAND_SLIVER_WIDTH=6`(336)、`ISLAND_SIZE_DELTA`(344-348)、`ISLAND_SHADOW_PAD=10`(351)、`ISLAND_TYPE_SCALE`(354-367)、`ISLAND_LIST_METRICS`(379-402)、`IslandListLayout`(405-412)、`islandListLayout()`(445-474)、`CLASSISLAND_TIME_TYPES`(513-518)、`buildCallTitle`(571-575) |
|
||||
| `packages/shared/src/island-layout.ts` | `ISLAND_COMPONENTS`(3-18)、`CLASSISLAND_ISLAND_METRICS`(20-36)、`IslandWeather`(38-44)、`IslandComponentNode/Scheme/Settings`(61-139)、`LessonReminderSettings` + `DEFAULT_LESSON_REMINDERS`(141-158)、`defaultIslandLayouts()`(217-255)、`normalizeIslandLayouts()`(256-404,行 12/节点 200/深度 6/方案 20 上限) |
|
||||
| `packages/shared/src/class-plan.ts` | `TimePointType`(4-5)、`TimePointDto`(6-21)、`ClassPlanDto`(39-54)、`ActiveClassPlanDto`(55-63)、`IslandTimePointDto`(76-87) |
|
||||
| `packages/shared/src/courseware.ts` | `COURSEWARE_MAX_BYTES`(2)、`COURSEWARE_TRANSFER_TIMEOUT_MS`(3)、`COURSEWARE_ISLAND_SIZE=424×132`(4)、分类与 `coursewareCategory`(5-27)、`CoursewareTransfer`(82-94) |
|
||||
| `packages/shared/src/motion.ts` | `EASE_OUT (0.16,1,0.3,1)`(24)、`EASE_IN_OUT (0.77,0,0.175,1)`(26)、`EASE_DRAWER (0.32,0.72,0,1)`(28)、SPRING 系列(48-58)、`--ch-*` 注入(211-238) |
|
||||
|
||||
### 1.3 主进程与渲染进程
|
||||
|
||||
| 文件 | 关键内容 |
|
||||
|---|---|
|
||||
| `packages/desktop-client/src/main/island.ts`(2445 行) | 尺寸常量(81-112)、`CLOSE_ANIMATION_MS=360`(121)、`TIMEOUTS`(124-132)、`pushNotification`(794-867)、`setClassState`(870-915)、`flushQueueAfterClass`(917-927)、`handleAction`(929-1077)、`hide/beginClose/finishClose`(1079-1192)、`removeNotification`(1210)、`activate/scheduleCollapse`(1248-1296)、`isImmediate/isOpenable`(689-702)、`mergeNotification`(713-724)、`pendingNotifications`(738-749)、`listLayout`(755-765)、`refreshViewport`(774-785)、`lessonShowing`(173-185)、`refreshLessonReminder`(192-212)、`coursewareShowing`(667-676)、`BLUR_GRACE_MS=500`/`BLUR_GRACE_TOUCH_MS=1200`(2287-2297)、`PREVIEW_DURATION_MS=30_000`(2300)、`MIN_CARD_HEIGHT=120`(2306)、心跳/重建(2315-2318) |
|
||||
| `packages/desktop-client/src/main/lesson-reminder.ts`(110 行) | 五类提醒判定顺序、5s/12s 窗口、maskUntil/endsAt 公式、id/entered |
|
||||
| `packages/desktop-client/src/main/island-weather.ts`(73 行) | Open-Meteo 固定参数、坐标校验、15min 缓存、60s 退避、8s 超时、64KB 上限、32 条缓存、stale |
|
||||
| `packages/desktop-client/src/main/ipc.ts` | `island:weather` IPC 入口(23) |
|
||||
| `packages/desktop-client/src/island/IslandApp.vue`(683 行) | 状态/胶囊摘要(66-157)、尺寸目标(188-200)、`isClosing`(73-80)、命中上报与穿透(402-516)、外观 CSS 变量(518-529)、模板层叠(573-681) |
|
||||
| `packages/desktop-client/src/island/ClassicNotifications.vue`(234 行) | 排序/列表/尺寸(21-58)、类型徽标(59-83)、列表渲染(162-208)、按钮行(219-231) |
|
||||
| `packages/desktop-client/src/island/LessonReminderContent.vue`(318 行) | 文案与倒计时(13-58)、斜切遮罩多边形/时序(59-102)、模板(126-193)、样式(195-317) |
|
||||
| `packages/desktop-client/src/island/lesson-ending.css`(16 行) | 蓝色秒数徽标 30×30/#0a84ff/12px |
|
||||
| `packages/desktop-client/src/island/CoursewareTransfer.vue`(132 行) | 424×132 定位、四阶段文案、元信息与进度条、样式 |
|
||||
| `packages/desktop-client/src/island/WeatherBrief.vue`(91 行) | 60s 轮询、坐标变化刷新、WMO 文案、建议、缓存标记 |
|
||||
| `packages/desktop-client/src/island/classic-island.css`(757 行) | token(49-90)、连续圆角+1px 描边+常驻投影(102-124)、胶囊固定内容盒(196-216)、收回不显示内容(226-232)、状态色(155-185) |
|
||||
| `packages/desktop-client/src/renderer/stores/notifications.ts`(148 行) | 未读计数、推送去重(87-93)、已读/全部已读(102-122)、缓存隔离 |
|
||||
|
||||
### 1.4 ClassIsland 侧(复用上一轮 parts 与源码)
|
||||
|
||||
- `parts/04-main-window.md`:行模型/模板/几何/可见性/鼠标淡出/分体/隐藏规则/编辑模式/抽屉/动画表(本文 §3.1、3.3、3.4、3.5、3.9 来源)。
|
||||
- `parts/05-components.md`:11 类组件与课程表组件行为、6 种附加信息、倒计时药丸、进度条 3px、空态与明天课表(本文 §3.2、3.7 来源)。
|
||||
- `parts/07-notifications.md`(本人上一轮产出):队列/优先级/两阶段/强提醒/音效(本文 §3.8、3.9 来源)。
|
||||
- `parts/10-settings.md`、`parts/11-other-windows.md`:设置页与窗口行为(本文仅引用术语与入口,不展开)。
|
||||
- `parts/14-animations.md`:动画别名表/时长常量/A 组岛动效/B 组提醒动效/F 组 ClassHelper 既有动效(本文 §3.12、§8.4.3 来源)。
|
||||
- ClassIsland 源码(上一轮已读,本文直接引用行号):`Services/LessonsService.cs`、`Services/NotificationHostService.cs`、`Shared/Models/Notification/NotificationPriority.cs`、`Controls/MainWindowLine.axaml(.cs)`、`XamlThemes/FluentTheme/Styles.axaml`、`Controls/SlantedMaskControl.cs`、`Views/TopmostEffectWindow.axaml.cs`、`Controls/NotificationEffects/RippleEffect.axaml.cs`、`Models/Settings.cs`、`Controls/Components/*`、`Controls/LessonsControls/*`、`ClassIsland.Core/Controls/HighlightBox.axaml`。
|
||||
|
||||
## 2. 关键默认值与参数表(交叉校验用)
|
||||
|
||||
### 2.1 ClassIsland 基准(Part 03 采用)
|
||||
|
||||
| 项 | 值 | 来源 |
|
||||
|---|---|---|
|
||||
| 行高 | 40 | `MainWindowLine.axaml:16` |
|
||||
| 行内容内边距 / 最小宽 | 12 / 20 | `FluentTheme/Styles.axaml:110` |
|
||||
| 行间距 | 5(0–150) | `Settings.cs:219` |
|
||||
| 圆角 | 8(0–20) | `Settings.cs:183-184` |
|
||||
| 背景不透明度 | 0.5 | `Settings.cs:64` |
|
||||
| 行不透明度 | 1.0(0.1–1) | `MainWindowLine.axaml:51` |
|
||||
| 字号 | 14/16/18/20 | `Settings.cs:197-200` |
|
||||
| 指针淡出 | 0.05;默认开、不反转 | `Settings.cs:193-194` |
|
||||
| 隐藏三开关 | 全 false | `Settings.cs:45,54,63` |
|
||||
| 排除进程 | `["explorer"]` | `Settings.cs:56-59` |
|
||||
| 遮罩斜切 | 5 区段、360ms、错峰 120ms、60° | `SlantedMaskControl.cs:284,298-308`;`Styles.axaml:175-180` |
|
||||
| 遮罩文字 | 260/250ms、scale 1.1→1 / 750ms | `Styles.axaml:329-352` |
|
||||
| 遮罩退出 | 200ms、scale 1→1.1、`(0.5,0,0.75,0)` | `Styles.axaml:376-398` |
|
||||
| 正文淡入淡出 | 200ms SineEaseIn | `Styles.axaml:419-451` |
|
||||
| 进度条 | 3px、50ms 线性 | `Styles.axaml:137-145` |
|
||||
| 强提醒涟漪 | 600ms 扩散 + 600ms 淡出 + 750ms 移除 | `RippleEffect.axaml.cs:86-109` |
|
||||
| 特效缩放默认 | 1.0 | `Settings.cs:150` |
|
||||
| 行宽过渡 | Fluent 300ms `(0.65,0,0.35,1)` / Classic 550ms `(0,1,0.5,1.1)` | `FluentTheme/Styles.axaml:269`;`ClassicTheme/Styles.axaml:207` |
|
||||
| 课程表设置默认 | 见 Part 03 §3.7.5 | `LessonControlSettings.cs:8-23` |
|
||||
|
||||
### 2.2 ClassHelper 既有(Part 08 保留)
|
||||
|
||||
| 项 | 值 | 来源 |
|
||||
|---|---|---|
|
||||
| 优先级 | LOW/NORMAL/HIGH/URGENT + RANK 0/1/2/3 | `types.ts:30`;`constants.ts:203-208` |
|
||||
| 超时 | pill 15s / afterClass 14s·25s / expanded 20s / urgent 45s / call 90s | `island.ts:124-132` |
|
||||
| 收回动画 | 360ms(随 speed) | `island.ts:121` |
|
||||
| 失焦宽限 | 鼠标 500ms / 触摸 1200ms | `island.ts:2287,2297` |
|
||||
| 预览 | 30s | `island.ts:2300` |
|
||||
| 列表度量 | 前 3 条、最多 20 行、`safetyPad 6`、行高 2.7×fontSize | `constants.ts:379-402` |
|
||||
| 尺寸增量 | expanded +156×186、urgent +172×202、call +188×218 | `constants.ts:344-348` |
|
||||
| 阴影留白 | 10 | `constants.ts:351` |
|
||||
| 细缝宽 | 6 | `constants.ts:336` |
|
||||
| 课程提醒 | 五类、5s/12s 窗口、prepare 60s、ending 60s(5–600) | `lesson-reminder.ts:38-72`;`island-layout.ts:150-158` |
|
||||
| 课程提醒条 | 40 高、min300/max800、圆角 8、bg #20202080、进度 2px | `LessonReminderContent.vue:196-317` |
|
||||
| 徽标 | 30×30 圆、#0a84ff、12px/600、`-N` | `lesson-ending.css:2-16` |
|
||||
| 天气 | Open-Meteo、15min 缓存、60s 退避、8s 超时、64KB、32 条 | `island-weather.ts:35-68` |
|
||||
| 课件卡 | 424×132、圆角 24、padding 17 24、进度 5px | `courseware.ts:4`;`CoursewareTransfer.vue:68-131` |
|
||||
| 弹簧 | stiffness 0.10 / damping 0.68 / 动量 35% / 单帧 ≤20% / snap 0.05 | `spring.ts`(Round1 brief §4 与 `parts/14` F1-F3) |
|
||||
|
||||
## 3. 裁决落点(写进文档的确定规则)
|
||||
|
||||
1. **fixed 形态重定义**:默认 `family='classisland'` 下 fixed = ClassIsland 信息行(日期+课程表、行高 40、圆角 8、背景 0.5、3px 进度条),气泡行内两阶段;`winisland` 保留胶囊+详情卡;升级/新装默认值不同(升级 winisland / 新装 classisland)。
|
||||
2. **排序**:ClassHelper 的「业务优先级 → 时间」为第一裁决;ClassIsland 的提供方优先级/通知等级**不引入**,仅允许 `level` 作为稳定次级键(防跨优先级反转)。
|
||||
3. **上课展示**:暂存规则保留;classisland 信息行上课保持可见(对齐 ClassIsland `HideOnClass=false`),普通通知不展开气泡、显示暂存角标;winisland 维持「上课隐藏整岛」旧规则。
|
||||
4. **课程提醒**:五类 kind 全保留;`ending` 只显示蓝色秒数徽标,**不实现** ClassIsland「即将下课」遮罩;`custom` 下 `ending/in-class` 不接管岛;徽标显示 `-N`,剩余 1 秒显示 `-1`(`ceil` 语义)。
|
||||
5. **进度条**:提醒条 2px、组件/行内 3px,两处并存不合并。
|
||||
6. **动画分工**:岛整体尺寸/圆角用 ClassHelper 弹簧;气泡内部遮罩/文字/进度用 ClassIsland CSS/WAAPI;`speed` 同比缩放,`animations=false` 直跳终态且几何一致。
|
||||
7. **强提醒**:新增独立 topmost-effect 窗口,600/600/750ms、`effectScale`、多屏、编辑模式不播;**不做音效/TTS**。
|
||||
8. **天气**:保留 Open-Meteo(15min/缓存标记/无官方预警),ClassIsland 的多模式/预警/预报不实现。
|
||||
9. **课件优先**:覆盖整岛(424×132);紧急或叫人在播时课件让位且消息不丢。
|
||||
10. **非目标**:自动化/插件/主题市场/管理端/Excel/音效 TTS/启动闪屏与 OOBE 一律不实现。
|
||||
|
||||
## 4. 未决问题 / 需其它 part 补齐(本 part 已按下列方式处理)
|
||||
|
||||
1. **`family` 字段的准确落盘键未定**:Lead 口径同时出现 `appearance.family` 与配置键 `islandAppearance.style`。本文档统一写作 `family`(注明以 parts-r/05 为准)。**需 stack 在 parts-r/05 定稿。**
|
||||
2. **信息行与气泡的几何关系**:气泡在 40 行内展开时,正文最多两行会导致行高增大。本文档定为「气泡阶段行高仍 40,正文最多 2 行截断」;若 ui-island 在 parts-r/07 决定允许行高临时增高(如 40→64),需同步修改 8.4.2 并更新动画参数。**需 ui-island 确认。**
|
||||
3. **`effectScale` / `effectEnabled` 字段**:本文档新增外观开关,需 design/stack 在 parts-r/06/05 中给出正式字段名与默认值(现为 `true` / `1.0`)。
|
||||
4. **`IslandState` 新增字段**(`family/pendingStaged/bubblePhase/bubbleDeadline`)与 `IslandNotification.level`、`IslandLessonReminder.progress/leftSeconds`:需 stack 在 parts-r/05 的 schema 扩展中登记,本文档按「只加不改」处理。
|
||||
5. **强提醒特效窗口的进程/文件归属**:本文档只定义行为与参数,具体文件(新增 `src/island/effect.*`、`src/main/effect-window.ts`)与 IPC 白名单需 stack 在 parts-r/04 落实。
|
||||
6. **作业「指纹」实现位置**:`docs/app/island.md:25` 提到本机刚录作业用指纹避免重复提醒自己,源码位置未在本次读取范围内定位;本文档只要求「在推送入口实现」,具体函数需 stack 补读 `src/main/*` 中作业推送链路。
|
||||
7. **「上课状态」的推送方**:`setClassState` 由主窗口/服务端同步调用,具体调用点在本次阅读范围外;本文档要求「服务端/主窗口下发为准」,需 stack 在 parts-r/02/04 标注现有调用链。
|
||||
8. **`endingsSeconds` 与 ClassIsland `ClassPrepareNotifySeconds` 的关系**:ClassHelper 用独立 `prepareSeconds/endingSeconds`(默认 60/60),ClassIsland 用 `ClassPrepareNotifySeconds=60`;本文档保留 ClassHelper 两字段,不做合并。
|
||||
9. **音效/TTS 若未来要做**:本文档明确不实现,并建议作为独立扩展项默认关闭(与 parts/07 的 ClassIsland 规格解耦)。
|
||||
10. **`custom` 下 `prepare/on-class/break` 临时接管岛内容的表现**:保留「提醒条接管」,但 ClassIsland 规格下 custom 应尽量不打断常驻行。本文档暂定「接管时保留行高 40、不替换常态行的其它行」,需 ui-island 在 parts-r/07 确认多行时接管范围。
|
||||
|
||||
## 5. 与其它 part 的边界
|
||||
|
||||
- 像素 token(颜色/圆角/阴影/字号变量):parts-r/06;本文只给业务相关像素(气泡行高、进度条、徽标、课件卡、课程提醒条)。
|
||||
- 岛/行/组件/编辑模式的结构与逐组件像素:parts-r/07;本文 §3 只给行为与判定顺序。
|
||||
- 动画总表与降级:parts-r/10;本文给 ms/曲线原始值,建议 parts-r/10 直接引用,避免二次估算。
|
||||
- schema/迁移/IPC 白名单:parts-r/05。
|
||||
- 设置页/编辑器 UI:parts-r/09;本文只给消息/课程相关开关的默认值。
|
||||
- 验收汇总:parts-r/12;本文 §8.14 可直接作为其中的消息与课程子集。
|
||||
@@ -0,0 +1,131 @@
|
||||
# 设计组 Round 2 分析记录(design)
|
||||
|
||||
本文件记录重构 Part 06(tokens)与 Part 10(动画映射)的源码依据、映射决策、跨 part 约定与未决问题。写作纪律:只读静态分析,未构建/未运行/未启动 Electron/未截图/未冒烟,未修改 `repos/`;只写 `parts-r/` 与 `analysis/`。
|
||||
|
||||
## 1. 已读文件清单
|
||||
|
||||
### 1.1 ClassHelper 文档与共享层
|
||||
|
||||
| 文件 | 范围 | 用途 |
|
||||
|---|---|---|
|
||||
| `repos/ClassHelper-master/docs/dev/winisland-design-tokens.md` | 全文 59 行 | 经典几何/自定义行度量/动画与命中入口的权威说明 |
|
||||
| `repos/ClassHelper-master/docs/dev/motion.md` | 全文 138 行 | 动效令牌单一来源、弹簧转 CSS、注入时机、四条硬约束 |
|
||||
| `repos/ClassHelper-master/docs/app/island.md` | 全文 79 行 | fixed/custom 行为、课程徽标、课件覆盖、动画开关语义 |
|
||||
| `repos/ClassHelper-master/docs/app/appearance.md` | 全文 101 行 | 深浅色、界面风格、动效语言、降低动态效果 |
|
||||
| `packages/shared/src/motion.ts` | 全文 242 行 | EASE_*、SPRING_*、MOTION_DURATION、motionCssVars |
|
||||
| `packages/shared/src/constants.ts` | 全文 680 行 | DEFAULT_ISLAND_APPEARANCE、RANGES、SIZE_DELTA、TYPE_SCALE、LIST_METRICS、SHADOW_PAD、SLIVER_WIDTH |
|
||||
| `packages/shared/src/island-layout.ts` | 全文 404 行 | CLASSISLAND_ISLAND_METRICS、IslandComponentNode、方案/行/节点默认值、normalize |
|
||||
| `packages/shared/src/courseware.ts` | 全文 94 行 | COURSEWARE_ISLAND_SIZE=424×132 |
|
||||
| `packages/shared/src/types.ts` | 1114-1233 行 | IslandLessonReminder、IslandNotification、IslandAppearance、IslandState |
|
||||
|
||||
### 1.2 ClassHelper 岛渲染层
|
||||
|
||||
| 文件 | 范围 | 用途 |
|
||||
|---|---|---|
|
||||
| `packages/desktop-client/src/island/IslandApp.vue` | 40-683 行(关键段 40-219、220-379、380-499、500-560) | 弹簧形变、目标尺寸/圆角、交叉淡入律、命中、样式注入 |
|
||||
| `packages/desktop-client/src/island/CustomIslandRuntime.vue` | 40-329、330-528 行 | 测量适配、弹簧、页面交叉、暂停规则、页面结构 |
|
||||
| `packages/desktop-client/src/island/ComponentNode.vue` | 100-219、340-456 行 | 组件渲染、滚动 keyframes、轮播索引、进度条、选中态 |
|
||||
| `packages/desktop-client/src/island/ClassicNotifications.vue` | 55-230 行(grep 定位) | 气泡/列表结构与尺寸计算 |
|
||||
| `packages/desktop-client/src/island/LessonReminderContent.vue` | 全文 318 行 | 课程提醒:5 区斜切遮罩、文字动画、进度条、徽标 |
|
||||
| `packages/desktop-client/src/island/CoursewareTransfer.vue` | 全文 132 行 | 课件覆盖卡尺寸/样式/进度 |
|
||||
| `packages/desktop-client/src/island/spring.ts` | 全文 115 行 | 弹簧参数与积分/钳制 |
|
||||
| `packages/desktop-client/src/island/squircle.ts` | 全文 81 行 | 超椭圆连续圆角 |
|
||||
| `packages/desktop-client/src/island/classic-island.css` | 全文 757 行 | 经典岛调色板、胶囊/展开布局、悬停/按压 |
|
||||
| `packages/desktop-client/src/island/custom-island.css` | 全文 205 行 | 自定义卡片/编辑器预览/铃铛 |
|
||||
| `packages/desktop-client/src/island/custom-runtime.css` | 全文 255 行 | 常驻窗布局、ClassIsland 底色覆盖、徽标入场 |
|
||||
| `packages/desktop-client/src/island/lesson-ending.css` | 全文 17 行 | 下课前秒数徽标 |
|
||||
| `packages/desktop-client/src/renderer/styles/island-editor.css` | 全文 417 行 | 编辑器预览、拖拽幽灵、放置高亮 |
|
||||
| `packages/desktop-client/src/renderer/styles/index.css` | 1-160、560-1012 行 | 主窗口 token、动效覆盖、reduced-motion、换肤 |
|
||||
| `packages/ui/src/tokens.css`、`packages/ui/src/theme.css` | 全文 | 应用外壳 token 层 |
|
||||
| `packages/desktop-client/src/island/main.ts` | 全文 | 岛渲染进程入口与动效 token 注入 |
|
||||
| `packages/desktop-client/src/main/config.ts` | island 相关 grep | 外观归一化与默认值 |
|
||||
| `packages/desktop-client/src/main/island.ts` | 70-140、225-295、500-590、750-830、1400-1520、1520-1650 行 + 常量 grep | 窗口几何/命中/淡入淡出/关闭时长/超时/预览/失焦宽限 |
|
||||
|
||||
### 1.3 ClassIsland 基准(复用 Round 1 产出)
|
||||
|
||||
`parts/03-design-tokens.md`、`parts/14-animations.md`、`parts/09-themes.md` 与 `analysis/design.md`(上一轮自产),以及必要处回查 `repos/ClassIsland`:`XamlThemes/FluentTheme/Styles.axaml`、`ClassicTheme/Styles.axaml`、`Controls/SlantedMaskControl.cs`、`Controls/MainWindowLine.cs`、`MainWindow.axaml.cs`、`RippleEffect.axaml.cs`、`RollingComponent.axaml.cs`、`SlideComponent.axaml`、`ComponentPresenter.axaml.cs`。
|
||||
|
||||
### 1.4 本轮 Lead 产出(对齐口径)
|
||||
|
||||
`parts-r/00-preamble.md`、`parts-r/01-objective.md`、`parts-r/11-compat-tests.md`、`parts-r/12-acceptance.md`、`parts-r/13-milestones.md`、`analysis/50-refactor-brief.md`。
|
||||
|
||||
## 2. 关键映射决策
|
||||
|
||||
| 编号 | 决策 | 依据 |
|
||||
|---|---|---|
|
||||
| D1 | 风格字段采用 Lead 裁决的 `appearance.family: 'classisland'|'winisland'`;旧 `style` 保留给 winisland 调色板,新增 `winislandStyle` 承载 | `parts-r/01-objective.md:60`、`analysis/50-refactor-brief.md:30`;防止与 Lead 汇总冲突 |
|
||||
| D2 | `family='classisland'` 才是默认;**老用户升级为 winisland**、新装为 classisland | `01-objective.md:60` |
|
||||
| D3 | classisland family 下不使用弹簧/squircle;几何动画一律 CSS transition | `01-objective.md:52` |
|
||||
| D4 | classisland 主题层:`theme: fluent|classic` + `colorScheme: light|dark|system`;winisland 恒深色 | ClassIsland 双主题(`App.Services.xaml.cs:297-315`)与 Theme=2 默认(`Settings.cs:32`) |
|
||||
| D5 | 遮罩实现抽公共组件复用(课程提醒已有实现,消息气泡复用),禁止第二份 | 现状 `LessonReminderContent.vue:59-102`;`12-acceptance.md:27` |
|
||||
| D6 | 进度条 classisland 3px/50ms 线性、winisland 2px/1s;统一用 `transform: scaleX` | ClassIsland `FluentTheme:137-145`;现状 `ComponentNode.vue:348-362` |
|
||||
| D7 | 滚动组件默认保留 ClassHelper 连续跑马灯,另提供 ClassIsland「40px/s+10s 暂停」模式 | 现状 `ComponentNode.vue:446-453`;ClassIsland `RollingComponent.axaml.cs:85-135` |
|
||||
| D8 | 系统 reduced-motion **不覆盖岛**,岛动画只由 `appearance.animations` 决定;`speed` 统一缩放时长;P2 才提供可选 `respectReducedMotion`(默认 false) | `docs/app/island.md:57`、`docs/dev/motion.md:78`;Lead 修正 |
|
||||
| D9 | fps/时长总原则:错误别「表演」,退场一律比入场快;所有时长 `/speed` | 现状实现与 `docs/dev/motion.md:66` |
|
||||
| D10 | token 单一来源放 `src/island/tokens.css`,与 `--ch-*`/`--wn-*`/`--custom-*` 分层 | `docs/dev/motion.md:53-59` 的注入纪律 |
|
||||
| D11 | **fixed 行高恒 40px**:气泡的遮罩/正文/进度条全部在行内完成,正文最多 2 行省略,不随内容增高、不为气泡扩窗;`maxCardHeight` 只用于 custom 多条列表与强提醒窗口 | Lead 修正;`repos/ClassIsland/.../FluentTheme/Styles.axaml:65`(`IslandContainerHeight=40`) |
|
||||
|
||||
## 3. Token 对照表(ClassIsland → 本轮 `--ci-*` → ClassHelper 既有)
|
||||
|
||||
| 语义 | ClassIsland 目标 | 本轮 token | ClassHelper 既有 | 动作 |
|
||||
|---|---|---|---|---|
|
||||
| 行高 | 40 | `--ci-row-h` | `--resident-height:40`(`custom-runtime.css:77`) | 统一 |
|
||||
| 行内边距 | 12 | `--ci-row-pad-x` | `--resident-padding`/`padding 0 12px` | 统一 |
|
||||
| 行最小宽 | 20 | `--ci-row-min-w` | 无 | 新增 |
|
||||
| 行间距 | 5(0–150) | `--ci-row-gap` | `scheme.spacing` 默认 5 | 保留 |
|
||||
| 组件间距 | 12(单侧 6) | `--ci-comp-gap` | `--row-gap` 默认 12 | 保留 |
|
||||
| 圆角 | 8(0–20) | `--ci-radius-island` | `radius` 默认 20(winisland) | 分 family |
|
||||
| 胶囊圆角 | — | 仅 winisland | `min(radius,h/2)` | 保留 |
|
||||
| 背景不透明度 | 0.5 | `--ci-opacity-bg` | `scheme.opacity` 0.5 | 保留 |
|
||||
| 窗口不透明度 | 1(阅读消息强制 1) | 由 `displayOpacity` 决定 | `main/island.ts:233-240` | 保留 |
|
||||
| 淡化 | 0.05 | `--ci-opacity-faded` | `CLASSISLAND_ISLAND_METRICS.fadedOpacity` | 保留 |
|
||||
| 背景色 | Fluent `#1C1C1C` / Classic `#202020`【推断】 | `--ci-bg` | `--wn-bg` 三套 | 分 family |
|
||||
| 描边 | 1px `rgba(255,255,255,.15)` | `--ci-border` | `--wn-border:.118` | 改值 |
|
||||
| 文字 5 级 | 100/85.5/77.3/52.9/36.5% | `--ci-text-1..5` | `--wn-text-1..3`(.92/.72/.58) | 改值+补齐 |
|
||||
| 强调色 | `#00BFFF` | `--ci-accent` | `#0a84ff` | 仅新装改默认 |
|
||||
| 强调淡底 | 10%/14% | `--ci-accent-soft(-strong)` | `color-mix 20/22/26%` | 改值 |
|
||||
| 状态色 | 红/橙/accent | `--ci-state-*` | `#ff453a`/`#ff9f0a`/accent | 保留值 |
|
||||
| 进度条 | 3px、轨道 15%、直角 | `--ci-progress-*` | 2px、`#ffffff24`、1px | 改值 |
|
||||
| 阴影 | `0 4 8 2 #48000000`、遮罩 `0 8 32 #66000000` | `--ci-shadow-*` | winisland drop-shadow 0 2 3 | 分 family |
|
||||
| 字号 | 14/16/18/20 | `--ci-fs-*` | `--secondary/--emphasized/--large` 默认 12/20/28 | 改值+派生 |
|
||||
| 字体 | HarmonyOS Sans SC 栈 | `--ci-font` | 系统栈 | 改栈不内置字体 |
|
||||
| 时长/曲线 | 300/550/360/120/260/250/750/200/100 | `--ci-dur-*`、`--ci-ease-*` | `--island-dur=320/speed`、`--ch-dur-*` | 新增 |
|
||||
| 层级 | 遮罩 2/文字 3/拖拽幽灵 10000 | `--ci-z-*` | `.drag-ghost 10000` | 新增 |
|
||||
| 窗口留白 | 10 | `--ci-shadow-pad` | `ISLAND_SHADOW_PAD=10` | 保留 |
|
||||
|
||||
## 4. 与其他 part 的接口约定
|
||||
|
||||
1. **Part 05(数据/迁移)**:请采用 `appearance.family/theme/colorScheme/winislandStyle` 四字段;迁移规则见 part 06 §6.12(幂等、只改仍为旧默认值的 accent/fontSize)。
|
||||
2. **Part 07(岛结构/组件)**:行高恒 40、行内边距 12、组件间距 12(单侧 6)、行间距 5、进度条 3px、圆角 8、字号四档由 `fontSize` 派生;**fixed 单条气泡也在 40px 行内、正文最多 2 行省略、不增高不扩窗**;`maxCardHeight` 只服务 custom 多条列表/强提醒窗口;分体行用 `--ci-radius-row`。
|
||||
3. **Part 08(消息/课程/强提醒)**:气泡时间线严格按 part 10 §10.2.1(360/120、260/250、750、600/100、200 退出);强提醒涟漪 600/600/750;课程徽标 `-1` 边界与进度条 50ms。
|
||||
4. **Part 09(编辑器/设置页)**:预览行 44→40、背景改 `--ci-bg`;风格/主题/深浅色切换即时预览;动画开关与 speed 滑杆沿用现有控件。
|
||||
5. **Part 02/04(现状与文件计划)**:tokens 落点为新增 `src/island/tokens.css` + 六个既有 CSS 改为引用;请把该文件列入文件计划。
|
||||
6. **Part 11/12(兼容/验收)**:动画时长误差 ≤16ms、fps ≥50/55、无残留 rAF、无窗口 bounds 逐帧变化;视觉验收仅 `--visual`。
|
||||
|
||||
## 5. 未决问题
|
||||
|
||||
| 编号 | 问题 | 影响 | 建议 |
|
||||
|---|---|---|---|
|
||||
| Q1 | Lead part 01 用 `appearance.family`,而 50-brief 原文写 `islandAppearance.style: 'classisland'|'winisland'` | 字段命名可能冲突 | 已按 Lead 的 `family` 写;Lead 已确认 06 字段名保持即可,其余由 stack 在 part 05 统一 |
|
||||
| Q2 | Fluent/Classic 具体色值(`SolidBackgroundFillColorSecondary/Base`)来自 FluentAvalonia NuGet,不在仓库 | 颜色有推断成分 | 已在 §6.2.6 标【推断】;建议以 `#1C1C1C`/`#202020`(深色)为初值,视觉验收时校准 |
|
||||
| Q3 | classisland family 的 `theme`/`colorScheme` 字段是否由 part 05 写入 normalize? | 迁移与设置页依赖 | **已请 stack 在 part 05 登记**;本部分字段名保持 `theme`/`colorScheme` 不变 |
|
||||
| Q4 | fixed 信息行的默认行内容/行宽在 part 07 未定稿 | tokens 只能给约束,无法给具体宽度 | 由 ui-island 在 part 07 给出;本部分只保证行高(恒 40)/内边距/最小宽/圆角/气泡不增高 |
|
||||
| Q5 | `appearance.fontSize` 在 classisland 下改为「body 基准」(默认 16)、winisland 保持 13 | 设置页文案/滑杆语义变化 | 已写入 §6.3;**Lead 已请 stack 在 part 05 登记语义**,windows 在 part 09 更新文案 |
|
||||
| Q6 | 滚动组件新增 `settings.mode: 'continuous'|'pause'` 字段 | schema 变更 | **Lead 已请 stack 在 part 05 登记**;默认 `continuous` |
|
||||
| Q7 | ~~气泡「内容超高时行高过渡」~~ **已按 Lead 修正关闭**:fixed 行高恒 40,气泡在行内、正文 2 行省略,不增高不扩窗 | 动画时长与扩窗顺序 | 已写入 part 10 §10.0 规则 4、A4、§10.2.1 与 X3;`maxCardHeight` 仅 custom 列表/强提醒窗口 |
|
||||
| Q8 | 强提醒特效「渲染缩放 1/0.75/0.5」是 ClassIsland 设置语义,ClassHelper 无对应字段 | 大屏教室显示尺寸 | 建议复用 `appearance` 新增 `effectScale: 'auto'|1|0.75|0.5`;**Lead 已请 stack 在 part 05 登记** |
|
||||
| Q9 | reduced-motion 不覆盖岛的策略与部分评审预期可能相反 | 无障碍验收口径 | **已按 Lead 修正定稿**:岛动画唯一开关 `appearance.animations`,`speed` 缩放时长;系统 reduced-motion 默认不覆盖,P2 可选 `respectReducedMotion`(默认 false);请 11/12 保持同口径 |
|
||||
| Q10 | `--ci-lesson-*` 重命名会影响 part 08 的课程组件与测试断言 | 兼容 | 已在 §6.1 给 alias 过渡方案;请 features 协同 |
|
||||
| Q11 | 老用户首次升级到 classisland family 是否弹一次「新风格可用」提示(UI 决策) | 用户感知 | 属 part 09/13;本部分不涉及 |
|
||||
|
||||
## 6. 自检
|
||||
|
||||
| 文件 | 中文字数(CJK) | 关键覆盖 | 验收小节 |
|
||||
|---|---|---|---|
|
||||
| `parts-r/06-tokens.md` | 4369 | 双风格模型、变量分层与速查表(80+ token)、颜色/字体/圆角/间距/阴影/透明/层级/DPI/深浅色、Fluent vs Classic 差异、迁移规则、常见错误与自查命令 | §6.15(14 条) |
|
||||
| `parts-r/10-animations.md` | 6734 | 现状动画基线 20 条、映射总表 84 条(A–L 十二组)、消息时间线、冲突选择点 11 条、性能降级矩阵、实现规范 10 条、逐文件清单 | §10.7(14 条) |
|
||||
|
||||
- 所有关键数值均标注 `packages/...:行号` 或 `repos/ClassIsland/...:行号`;无法确认的值标【推断】并在上表记录。
|
||||
- 未执行任何构建/运行/截图/冒烟命令;未修改 `repos/`。
|
||||
- 术语遵循 `parts-r/00-preamble.md` §0.5:灵动岛/岛、fixed、custom、winisland、ClassIsland 风格、行、组件、方案、消息、强提醒、无头验证。
|
||||
- 默认值口径与 Lead 裁决一致:默认 `family='classisland'`、老用户升级 `winisland`;`fixed` 在 classisland 下为 40px 信息行。
|
||||
@@ -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 标准超额满足)。
|
||||
@@ -0,0 +1,197 @@
|
||||
# analysis/windows.md — Part 10(设置中心)与 Part 11(其它窗口)的工作底稿
|
||||
|
||||
负责人:windows(Part 10 / Part 11)
|
||||
工作方式:只读静态分析。未构建、未运行、未截图。所有结论来自源码文本与行号。
|
||||
|
||||
## 1. 已读文件清单(含读取范围)
|
||||
|
||||
### 1.1 设置中心(Part 10 证据)
|
||||
|
||||
| 文件 | 行数 | 读取范围 | 用途 |
|
||||
|---|---|---|---|
|
||||
| `repos/ClassIsland/ClassIsland/Views/SettingsWindowNew.axaml` | 266 | 全量 | 窗口尺寸、标题栏、导航、抽屉、遮罩、菜单 |
|
||||
| `repos/ClassIsland/ClassIsland/Views/SettingsWindowNew.axaml.cs` | 883 | 全量 | 导航构建、过滤、缓存、关闭/重启、URI、菜单动作 |
|
||||
| `repos/ClassIsland/ClassIsland/Models/Settings.cs` | 2655 | 1–900 精读 + 全部字段声明 grep(32–222、1836–1875) | 所有设置默认值 |
|
||||
| `Views/SettingPages/GeneralSettingsPage.axaml(.cs)` | 315 / 100 | 全量 | 基本页 |
|
||||
| `Views/SettingPages/AppearanceSettingsPage.axaml(.cs)` | 595 / 57 | 全量 | 外观页 |
|
||||
| `Views/SettingPages/WindowSettingsPage.axaml` | 276 | 全量 | 窗口页 |
|
||||
| `Views/SettingPages/ClockSettingsPage.axaml` | 95 | 全量 | 时钟页 |
|
||||
| `Views/SettingPages/StorageSettingsPage.axaml` | 111 | 全量 | 存储页 |
|
||||
| `Views/SettingPages/PrivacySettingsPage.axaml` | 42 | 全量 | 隐私页 |
|
||||
| `Views/SettingPages/AdvancedSettingsPage.axaml` | 77 | 全量 | 高级页 |
|
||||
| `Views/SettingPages/ErrorSettingsPage.axaml` | 35 | 全量 | 错误页 |
|
||||
| `Views/SettingPages/TestSettingsPage.axaml` | 17 | 全量 | 调试测试页 |
|
||||
| `Views/SettingPages/RefreshingSettingsPage.axaml` | 159 | 全量 | 翻新与迎新页 |
|
||||
| `Views/SettingPages/ManagementSettingsPage.axaml` | 117 | 全量 | 集控页 |
|
||||
| `Views/SettingPages/ManagementPolicySettingsPage.axaml` | 113 | 全量 | 集控策略页 |
|
||||
| `Views/SettingPages/ManagementCredentialsSettingsPage.axaml` | 101 | 全量 | 集控凭据页 |
|
||||
| `Views/SettingPages/AboutSettingsPage.axaml` | 319 | 全量 | 关于页 |
|
||||
| `Views/SettingPages/WeatherSettingsPage.axaml` | 332 | 全量 | 天气页 |
|
||||
| `Views/SettingPages/UpdateSettingsPage.axaml` | 403 | 全量 | 更新页 |
|
||||
| `Views/SettingPages/ThemesSettingsPage.axaml` | 368 | 全量 | 主题页 |
|
||||
| `Views/SettingPages/NotificationSettingsPage.axaml` | 497 | 全量 | 提醒页 |
|
||||
| `Views/SettingPages/ComponentsSettingsPage.axaml` | 644 | 全量 | 组件页 |
|
||||
| `Views/SettingPages/AutomationSettingsPage.axaml` | 402 | 全量 | 自动化页 |
|
||||
| `Views/SettingPages/PluginsSettingsPage.axaml(.cs)` | 884 / 680 | axaml 全量;cs 1–80 | 插件页 |
|
||||
| `Views/SettingPages/DebugPage.axaml` | 133 | 全量 | 调试页 |
|
||||
| `ClassIsland.Core/Abstractions/Controls/SettingsPageBase.cs` | 79 | 全量 | 页面基类、抽屉/重启命令 |
|
||||
| `ClassIsland.Core/Extensions/Registry/SettingsWindowRegistryExtensions.cs` | 81 | 全量 | 页面/分组注册机制 |
|
||||
| `ClassIsland.Core/Services/Registry/SettingsWindowRegistryService.cs` | 21 | 全量 | 注册表 |
|
||||
| `ClassIsland.Core/Attributes/SettingsPageInfo.cs` | 47 | 全量 | 页面元数据定义 |
|
||||
| `ClassIsland.Core/Enums/SettingsWindow/SettingsPageCategory.cs` | 24 | 全量 | 分类枚举与排序 |
|
||||
| `ClassIsland.Core/Attributes/GroupAttribute.cs` | 13 | 全量 | 分组 id |
|
||||
| `ClassIsland.Core/StylesBase.axaml` | 341 | 1–340 | settings-container、cardContainer、Slider tooltip、动画级别相关样式 |
|
||||
| `ClassIsland.Core/ThemeBase.axaml` | 57 | 全量 | `SettingsContainerWidth=960`、导航图标尺寸 20、开关默认「开/关」 |
|
||||
| `ClassIsland.Core/Controls/ListDetailView.axaml(.cs)` | 72 / 91 | 全量 | 设置页两栏布局、压缩阈值 800 |
|
||||
| `ClassIsland.Core/Controls/DrawerHost.axaml(.cs)` | 87 / 133 | 全量 | 设置抽屉宽度/动画/交互 |
|
||||
| `ClassIsland.Core/Controls/MyWindow.cs` | 244 | 全量 | 窗口基类、Mica、F3/F6/F7、Toast adorner |
|
||||
| `ClassIsland/App.Services.xaml.cs` | 326 | 130–209 | 页面注册顺序、分组、Excel/窗口 DI |
|
||||
| `ClassIsland/ViewModels/SettingsNewViewModel.cs` | 207 | 全量 | 窗口 VM 字段 |
|
||||
| `ClassIsland/Services/SettingsService.cs` | 294 | 100–294 | 即时保存、设置叠层、迁移 |
|
||||
| `ClassIsland/Views/SettingPages/PluginsSettingsPage.axaml.cs` | 680 | 1–80 | 插件市场首次刷新策略(7 天) |
|
||||
|
||||
### 1.2 其它窗口(Part 11 证据)
|
||||
|
||||
| 文件 | 行数 | 读取范围 |
|
||||
|---|---|---|
|
||||
| `Views/WelcomeWindow.axaml(.cs)` | 30 / 244 | 全量 |
|
||||
| `Views/WelcomePages/WelcomePage.axaml(.cs)` | 102 / 70 | 全量 |
|
||||
| `Views/WelcomePages/LicensePage.axaml` | 44 | 全量 |
|
||||
| `Views/WelcomePages/RefreshingPage.axaml` | 91 | 全量 |
|
||||
| `Views/WelcomePages/GeneralPage.axaml` | 50 | 全量 |
|
||||
| `Views/WelcomePages/ColorThemePage.axaml` | 81 | 全量 |
|
||||
| `Views/WelcomePages/AppearancePage.axaml` | 80 | 全量 |
|
||||
| `Views/WelcomePages/SystemPage.axaml` | 101 | 全量 |
|
||||
| `Views/WelcomePages/FinishPage.axaml` | 99 | 全量 |
|
||||
| `Controls/OobeIntroAnimationControl.axaml(.cs)` | 144 / 165 | 全量 |
|
||||
| `Views/SplashWindow.axaml(.cs)` | 100 / 131 | 全量 |
|
||||
| `Services/SplashService.cs` | 93 | 全量 |
|
||||
| `Views/CrashWindow.axaml(.cs)` | 99 / 86 | 全量 |
|
||||
| `Views/RecoveryWindow.axaml` | 22 | 全量 |
|
||||
| `Views/RecoveryPages/HomePage.axaml` | 85 | 全量 |
|
||||
| `Views/RecoveryPages/RecoverBackupPage.axaml` | 45 | 全量 |
|
||||
| `Views/UpdateProgressWindow.xaml` | 39 | 全量 |
|
||||
| `Views/TimeAdjustmentWindow.axaml` | 101 | 全量(cs 未读) |
|
||||
| `Views/ClassChangingWindow.axaml(.cs)` | 273 / 193 | 全量 |
|
||||
| `Views/ClassPlanDetailsWindow.axaml` | 199 | 全量(cs 未读) |
|
||||
| `Views/ExcelImportWindow.xaml` | 992 | 全量 |
|
||||
| `Views/ExcelImportWindow.xaml.cs` | 824 | 1–45、320–429、735–824 + grep(整文件被 `#if false` 包裹) |
|
||||
| `Views/ExcelExportWindow.xaml` | 301 | 全量 |
|
||||
| `Views/ExcelExportWindow.xaml.cs` | 539 | 1–30(`#if false`,未读其余) |
|
||||
| `Views/DataTransferWindow.axaml(.cs)` | 20 / 57 | 全量 |
|
||||
| `Views/DataTransferPage.axaml` | 273 | 全量 |
|
||||
| `Views/DataTransferPage.axaml.cs` | 803 | 1–120 + grep(ImportDescription) |
|
||||
| `Views/TutorialCenterWindow.axaml(.cs)` | 249 / 85 | 全量 |
|
||||
| `Views/TutorialControllerWindow.axaml` | 46 | 全量(cs 未读) |
|
||||
| `Views/TutorialEditorWindow.axaml` | 378 | 全量(cs 未读) |
|
||||
| `Views/TutorialScriptEditWindow.axaml` | 29 | 全量(cs 未读) |
|
||||
| `Views/AuthorizeWindow.axaml` | 153 | 全量(cs 未读) |
|
||||
| `Controls/AuthorizeProvider/PasswordAuthorizeProvider.axaml` | 67 | 全量 |
|
||||
| `Controls/JoinManagementDialog.axaml` | 64 | 全量 |
|
||||
| `Views/AppLogsWindow.axaml` | 178 | 全量(cs 未读) |
|
||||
| `Views/ConfigErrorsWindow.xaml` | 106 | 全量 |
|
||||
| `Views/InstanceExistedWindow.xaml` | 54 | 全量 |
|
||||
| `Views/WindowsPicker.xaml` | 150 | 全量 |
|
||||
| `Views/WallpaperPreviewWindow.xaml` | 74 | 全量 |
|
||||
| `Views/TopmostEffectWindow.axaml` | 35 | 全量 |
|
||||
| `Views/ClearNotificationButtonWindow.xaml` | 15 | 全量 |
|
||||
| `Views/RefreshingScopesConfigDialog.axaml` | 60 | 全量 |
|
||||
| `Views/WindowRuleDebugWindow.axaml` | 30 | 全量 |
|
||||
| `Views/ScreenshotHelperWindow.axaml` | 37 | 全量 |
|
||||
| `Views/FeatureDebugWindow.xaml` | 246 | 1–120(其余为内部测试页签) |
|
||||
| `Views/DevPortalWindow.axaml` | 269 | 全量 |
|
||||
| `Views/ProfileSettingsWindow.axaml` | 2004 | 1–80(仅窗口外壳;内容归 part 06) |
|
||||
|
||||
## 2. 设置页面清单(导航顺序 = 注册顺序,证据 `App.Services.xaml.cs:156-184`、`SettingsWindowNew.axaml.cs:145-227`)
|
||||
|
||||
| # | id | 名称 | category | 分组 | 图标(未选/选中) | 关键策略过滤 |
|
||||
|---|---|---|---|---|---|---|
|
||||
| 1 | general | 基本 | Internal | classisland.general(通用) | EF27/EF26(默认) | DisableSettingsEditing |
|
||||
| 2 | clock | 时钟 | Internal | 通用 | E4C4/E4C3 | 同上 |
|
||||
| 3 | storage | 存储 | Internal | 通用 | E6B7/E6B6 | 同上 |
|
||||
| 4 | privacy | 隐私 | Internal | 通用 | EF65/EF64 | 同上 |
|
||||
| 5 | refreshing | 翻新与迎新 | Internal | 通用 | E0B8/E0B9 | 同上 |
|
||||
| 6 | advanced | 高级 | Internal | 通用 | F49F/F49E | 同上 |
|
||||
| 7 | components | 组件 | Internal | classisland.mainwindow(主界面) | E06F/E06F | 同上 |
|
||||
| 8 | appearance | 外观 | Internal | 主界面 | E51E/E51D | 同上 |
|
||||
| 9 | window | 窗口 | Internal | 主界面 | F485/F484 | 同上 |
|
||||
| 10 | notification | 提醒 | Internal | — | E02B/E02A | 同上 |
|
||||
| 11 | weather | 天气 | Internal | — | F44F/F44E | 同上 |
|
||||
| 12 | automation | 自动化 | Internal | — | EEF1/EEF0 | 同上 |
|
||||
| 13 | update | 更新 | Internal | — | E161/E160 | 注册条件:AllowedPackageTypes |
|
||||
| 14 | classisland.plugins | 插件 | External | — | E071/E071 | FullWidthPage;DisableSettingsEditing |
|
||||
| 15 | classisland.themes | 主题 | External | — | E6AF/E6AE | 同上 |
|
||||
| 16 | test-settings-page | 测试页面 | Debug | — | 默认 | DisableDebugMenu / IsDebugOptionsEnabled |
|
||||
| 17 | debug | 调试 | Debug | — | E2C8/E2C7 | 同上 |
|
||||
| 18 | about | 关于 ClassIsland | About | — | E9E4/E9E3 | 无(始终可见) |
|
||||
| 19 | management | 集控 | About | — | 默认 | hideDefault |
|
||||
| 20 | management.credentials | 集控凭据设置 | About | — | 默认 | hideDefault |
|
||||
| 21 | management.policy | 集控策略 | About | — | 默认 | hideDefault |
|
||||
| 22 | _error | 出错啦! | About | — | 默认 | hideDefault(错误页) |
|
||||
|
||||
设置窗口:`1240×550`,`MinWidth=560`,导航窗格 `OpenPaneLength=283`,内容限宽 `960`,压缩阈值 `800`,标题栏高 `48`(`SettingsWindowNew.axaml:16-22`、`:52-60`、`:92-104`、`.cs:135`、`:437-446`)。
|
||||
|
||||
## 3. 窗口清单表
|
||||
|
||||
| 窗口/页面 | 尺寸 (W×H) | 最小/最大 | 模态/单例 | 关键样式 | 证据 |
|
||||
|---|---|---|---|---|---|
|
||||
| 设置窗口 SettingsWindowNew | 1240×550 | MinW 560 | 非模态单例 | Mica、自定义标题栏 48、导航 283 | `SettingsWindowNew.axaml:16-22` |
|
||||
| 欢迎向导 WelcomeWindow | 800×600 | 不可缩放 | 模态(ShowAsDialog) | Mica、CenterScreen | `WelcomeWindow.axaml:14-20` |
|
||||
| 闪屏 SplashWindow | 400×100 | — | 非模态、置顶 | 无边框、背景透明、Acrylic、暗色 | `SplashWindow.axaml:12-23` |
|
||||
| 崩溃 CrashWindow | 800×450 | — | 独立 | Mica | `CrashWindow.axaml:13-16` |
|
||||
| 恢复 RecoveryWindow | 450×600 | — | 主窗口(-m -r) | 无 Mica 声明 | `RecoveryWindow.axaml:14` |
|
||||
| 更新进度 UpdateProgressWindow | 300×100 | 不可缩放 | 置顶/手动定位 | 纯色 | `UpdateProgressWindow.xaml:9-24` |
|
||||
| 对齐铃声 TimeAdjustmentWindow | 600×330 | 不可缩放 | CenterOwner | Mica | `TimeAdjustmentWindow.axaml:11-16` |
|
||||
| 换课 ClassChangingWindow | 600×250(SizeToContent) | Min 730×175 | CenterScreen | Mica | `ClassChangingWindow.axaml:17-26` |
|
||||
| 课表详细信息 ClassPlanDetailsWindow | 800×500 | — | 独立 | Mica、三列 1*/5px/2* | `ClassPlanDetailsWindow.axaml:14-23` |
|
||||
| Excel 导入 | 最大化(设计 800×450) | — | 模态 | 源码停用,本实现 P1 重建(xlsx) | `ExcelImportWindow.xaml:27-34` |
|
||||
| Excel 导出 | 1400×700、最大化 | — | 独立 | 源码停用,本实现 P1 重建(xlsx) | `ExcelExportWindow.xaml:14-25` |
|
||||
| 数据迁移 DataTransferWindow | 800×600 | 不可缩放 | 模态(ShowAsDialog) | Mica | `DataTransferWindow.axaml:9-18` |
|
||||
| 授权 AuthorizeWindow | 500×SizeToContent | MinH 300 / MaxH 700 | 模态、置顶 | — | `AuthorizeWindow.axaml:14-24` |
|
||||
| 加入管理 JoinManagementDialog | 400×Auto | 不可缩放 | 对话框 | — | `JoinManagementDialog.axaml:12-15` |
|
||||
| 教学中心 TutorialCenterWindow | 1240×550 | — | 非模态单例 | Mica、SplitView 328 | `TutorialCenterWindow.axaml:14`、`:58-63` |
|
||||
| 教程控制条 TutorialControllerWindow | SizeToContent | 不可缩放 | 置顶无边框 | Acrylic、透明 | `TutorialControllerWindow.axaml:10-17` |
|
||||
| 教程编辑器 TutorialEditorWindow | 最大化 | — | 独立 | 五列 220/Auto/*/Auto/328 | `TutorialEditorWindow.axaml:15`、`:239` |
|
||||
| 教程脚本编辑 TutorialScriptEditWindow | 800×520 | 480×320 | 独立 | 深色代码编辑器 | `TutorialScriptEditWindow.axaml:9-11` |
|
||||
| 日志 AppLogsWindow | 1200×600 | — | 非模态单例 | Mica | `AppLogsWindow.axaml:15` |
|
||||
| 配置错误 ConfigErrorsWindow | 1200×600 | — | 独立 | 纯色 | `ConfigErrorsWindow.xaml:18` |
|
||||
| 实例已存在 InstanceExistedWindow | 800×450 | 不可缩放 | 独立 | 纯色 | `InstanceExistedWindow.xaml:20-22` |
|
||||
| 窗口选择 WindowsPicker | 1300×600 | — | 对话框 | MaterialDesign 混合 | `WindowsPicker.xaml:13` |
|
||||
| 壁纸预览 WallpaperPreviewWindow | 800×450 | — | CenterOwner | 纯色 | `WallpaperPreviewWindow.xaml:11` |
|
||||
| 顶层特效 TopmostEffectWindow | 1×1(运行时全屏) | 不可缩放 | 置顶无边框 | 透明 | `TopmostEffectWindow.axaml:8-15` |
|
||||
| 清除通知按钮 ClearNotificationButtonWindow | SizeToContent | — | 不实现(源码 `#if false`) | 空按钮遗留 | `ClearNotificationButtonWindow.xaml:8-11` |
|
||||
| 翻新范围 RefreshingScopesConfigDialog | 400×600 | 不可缩放 | 模态 | — | `RefreshingScopesConfigDialog.axaml:9-14` |
|
||||
| 窗口规则调试 WindowRuleDebugWindow | 400×Auto | — | 置顶 | Mica | `WindowRuleDebugWindow.axaml:9-14` |
|
||||
| 截图辅助 ScreenshotHelperWindow | 未设(Auto) | — | 独立 | — | `ScreenshotHelperWindow.axaml:1-10` |
|
||||
| 功能调试 FeatureDebugWindow | 800×450 | — | 独立(开发) | 纯色 | `FeatureDebugWindow.xaml:28` |
|
||||
| DevPortal | 1200×700 | — | 独立(开发) | Mica | `DevPortalWindow.axaml:17-21` |
|
||||
| OOBE 各页 | 800×600 内 | — | 导航页 | settings-container 限宽 600 | 各 `WelcomePages/*.axaml` |
|
||||
| 数据迁移页 | 800×600 内 | — | Carousel 5 页 | 限宽 600 | `DataTransferPage.axaml:17-23` |
|
||||
| 恢复子页 | 450×600 内 | — | Frame | — | `RecoveryPages/*.axaml` |
|
||||
|
||||
## 4. 关键判定与发现
|
||||
|
||||
1. **设置持久化是「逐属性即时写盘」**:`SettingsService.SettingsChanged` 在每个属性变化后调用 `SaveSettings(propertyName)`(`Services/SettingsService.cs:261-280`、`:171-179`);`[JsonIgnore]` 字段(`IsSentryEnabled`、`ShowSellingAnnouncement`)不写 `Settings.json`(`Models/Settings.cs:518-535`、`:2615-2628`)。
|
||||
2. **设置叠层**:`SettingsOverlays` JSON 键名为 `SettingsOverlay`;叠层用 `"@"` 保存原始值,`guid` 为各写入者(`Models/Settings.cs:263-273`、`SettingsService.cs:191-259`)。用户在 UI 改任意属性会清掉该属性全部叠层。
|
||||
3. **页面缓存**:`SettingsPagesCachePolicy` 仅在两处使用(`SettingsWindowNew.axaml.cs:425-428`、`:513-516`);`0` 不缓存、`1` 窗口内缓存、`>=2` 跨窗口缓存为推断。
|
||||
4. **OOBE 实际为 8 页**(`WelcomeWindow.axaml.cs:64-73`),不是任务描述中的「9 页」;页序为 欢迎/许可/翻新/基本/颜色主题/外观/系统/完成,且按 isRefreshing/isOnboarding 条件裁剪。
|
||||
5. **Excel 导入/导出源码为停用遗留**:两个 code-behind 文件整体被 `#if false` 包裹(`ExcelImportWindow.xaml.cs:1`、`ExcelExportWindow.xaml.cs:1`),DI 注册被注释(`App.Services.xaml.cs:204-205`),且原实现依赖 WPF/`ReoGrid`/`System.Windows.Forms`。**Lead 最终裁决:本实现按 P1 必须实现(用 `xlsx` 重建,ReoGrid/WPF 仅作参考),与 part 06 口径一致**;Part 11 已按此改写并给出 `xlsx`/Vue 网格技术约束。
|
||||
6. **无通知中心窗口**:全仓库 `Views/` 下不存在通知中心类窗口;提醒呈现依赖主界面行 + 强提醒特效(part 07 范围)。Lead 已确认该结论并在 part 01 修正提法;Part 11 明确「不得创建通知中心窗口」。
|
||||
6b. **ClearNotificationButtonWindow 为 `#if false` 遗留**(内容仅空按钮):Lead 裁决**不实现**,清除提醒改由主界面右键菜单「清除全部提醒」承担(归 part 04/07)。Part 11 已改写为「不实现」,不再列为实现窗口。
|
||||
7. **设置抽屉**:统一为右侧抽屉,动画 `250ms cubic-bezier(0,0,0,1)`,`Esc`/点遮罩关闭,只有 `IThemeService.AnimationLevel>=1` 才启用动画(`DrawerHost.axaml:42-59`、`.cs:70-72`、`:78-118`)。不同页面抽屉宽度:实验性 332、城市搜索 320、主题排序 300、主题错误 450、插件源 500、插件更新 320、更新下载 450、更新日志 500、提醒源 500、规则集 600。
|
||||
8. **响应式**:设置窗口 `<800px` 进入压缩模式;ListDetailView 自身也有 `<800px`(`MinCompressWidth=800`)压缩阈值,因此提醒/插件/自动化页在 800px 附近会二次压缩。
|
||||
9. **标题栏右侧「金刚键空位」140px** 与 macOS 左侧 60px 是 FluentAvalonia AppWindow 的窗口控制区预留(`SettingsWindowNew.axaml:120-126`、`:252`)。
|
||||
10. **调试快捷键**:F3/F6/F7 是窗口基类统一行为,不限于设置窗口(`MyWindow.cs:115-166`)。
|
||||
|
||||
## 5. 未决问题 / 缺口(交给 Lead 决策)
|
||||
|
||||
1. **FluentAvalonia 控件自带几何值缺失**:`SettingsExpander`/`SettingsExpanderItem` 的行高、内边距、圆角、图标槽宽度来自 FluentAvalonia 主题包,仓库中只有覆盖样式(如 `MinHeight` 调整、`CornerRadius` 覆盖),没有完整数值。Part 10 中相关数值已标注【推断】(建议实现时取 `min-height: 64px`、`padding: 16px`、圆角 4–7px)。
|
||||
2. **`SettingsPagesCachePolicy = 2` 的语义**为推断(源码只区分 `>=1` 与 `<=1`)。若 Lead 有 1.x 文档可确认。
|
||||
3. **部分设置页的 .cs 行为未读**(`WindowSettingsPage.axaml.cs`、`NotificationSettingsPage.axaml.cs`、`UpdateSettingsPage.axaml.cs` 等):其「立即生效 vs 重启」结论主要来自 XAML 绑定 + `RequestRestart` 调用点。已确认需重启:`AnimationLevel`、`IsWaitForTransientDisabled`;其余(渲染模式、系统标题栏、Qt 缩放)标注为推断。
|
||||
4. **ProfileSettingsWindow(档案编辑,2004 行)与 EditModeView(编辑模式)** 只记录了窗口外壳参数(`MinWidth=750`、`1100×600`、Mica、标题「档案编辑」),内容归 part 06 / part 04。若 Lead 希望 Part 11 覆盖其内部三栏布局,需要追加分配。
|
||||
5. **TimeAdjustmentWindow 的校准数学、TopmostEffectWindow 的全屏放置逻辑、TutorialControllerWindow 的定位逻辑**均在未读的 .cs 中(分别为 .cs 6173/4461/2568 字节),本文只给出 UI 规格与推断行为;如需精确算法需再读这三个文件。
|
||||
6. **Excel 功能已裁决**:Lead 定为 **P1 必须实现(xlsx 重建;ReoGrid/WPF 仅参考)**,与 part 06 同步;Part 11 已删除「可选/遗留、默认不实现」措辞并补齐技术约束与验收项。
|
||||
7. **通知中心**(简报 §6 中 part 11 的关键词)在源码中不存在;建议 Lead 在 part 07 中说明提醒的呈现位置,并在总纲中更正该关键词。
|
||||
8. **OOBE 页数与简报不一致**(8 vs 9);建议以源码为准。
|
||||
9. **「搜索设置」功能不存在**:任务描述提到「设置中心:导航/搜索」,但 `SettingsWindowNew` 无搜索框。Part 10 已注明不得编造。
|
||||
10. **多语言/本地化**:设置页与窗口文案在源码中为硬编码中文(未走 `Localization` 资源)。Lead 裁决:保留中文字面量作为规格,但**要求集中到常量文件**(Part 10 §10.5 第 8 条、Part 11 §11.1 第 6 条已写入)。
|
||||
Reference in new issue
Block a user