Adds the full documentation set for the planned desktop pet feature under docs/features/desktop-pet: README, PRD, user stories, logic design, UI design, and technical design. The pet is scoped as a lightweight always-on entry point for quick drafting, drag-and-drop staging, and task status at a glance; it does not introduce a second Ask/Execute channel, task execution path, or independent task-state store. Design only, no implementation yet.
208 lines
11 KiB
Markdown
208 lines
11 KiB
Markdown
# 桌面宠物 UI 设计
|
||
|
||
## 文档信息
|
||
|
||
| 项目 | 内容 |
|
||
| --- | --- |
|
||
| 状态 | 设计中 |
|
||
| 版本 | 0.1 |
|
||
| 日期 | 2026-09-03 |
|
||
| 关联 PRD | [桌面宠物 PRD](./prd.md) |
|
||
| 功能逻辑 | [功能逻辑设计](./logic-design.md) |
|
||
| 全局规范 | [GoodBuddy 统一界面设计系统](../../../UI-DESIGN.md) |
|
||
|
||
本文定义设置中的“桌面宠物”页面和独立宠物窗口的界面。所有颜色、间距、字体、通知、
|
||
Switch/Checkbox、焦点和响应式规则以全局设计系统为准;宠物窗口是应用内唯一不使用标准
|
||
`PageShell` 的持久界面,其例外范围在第 4 节明确限定。
|
||
|
||
## 1. 设置页面信息架构
|
||
|
||
设置中心新增“桌面宠物”一级分类,使用 `standard` PageShell,不使用页签,按以下顺序
|
||
纵向排列:
|
||
|
||
```text
|
||
桌面宠物
|
||
在桌面上保留一个轻量入口,随时起草消息、拖入文件或查看任务状态
|
||
|
||
启用桌面宠物 [Switch 关]
|
||
关闭后不在桌面上显示任何宠物窗口或提示
|
||
|
||
—— 以下设置仅在启用后可编辑,保持可见但降低强调度 ——
|
||
|
||
外观
|
||
角色 [分段选择:三到四个内置角色缩略图]
|
||
尺寸 [滑块 小 · 中 · 大]
|
||
透明度 [滑块]
|
||
动画强度 [滑块 关闭 · 轻量 · 完整]
|
||
[恢复默认外观]
|
||
|
||
位置与窗口
|
||
始终置顶 [Switch 开]
|
||
贴边吸附 [Switch 开]
|
||
|
||
提示
|
||
安静模式(不显示完成 / 失败气泡) [Switch 关]
|
||
```
|
||
|
||
- 总开关是本页唯一决定宠物窗口存在与否的控件,符合 `INV-3`;其余控件在总开关关闭时
|
||
保持可见但不可交互,说明文字保持“关闭后不在桌面上显示任何宠物窗口或提示”。
|
||
- 二元持久状态一律使用共享 Switch;角色选择使用共享 `SegmentedControl`(3-4 个内置
|
||
角色,符合数量上限);尺寸、透明度和动画强度使用标准滑块控件并显示当前取值。
|
||
- “恢复默认外观”只重置本区域三项外观设置,不改变总开关、位置或安静模式,与
|
||
[功能逻辑](./logic-design.md) 中“恢复默认外观”的范围一致。
|
||
- 页面不提供“立即显示 / 隐藏”按钮:暂时隐藏的入口固定放在托盘菜单,避免在设置页和
|
||
托盘中出现两个含义相近但状态不同步的控件。
|
||
|
||
## 2. 首次启用与关闭反馈
|
||
|
||
- 开启总开关后宠物窗口在默认位置出现,不产生任何应用通知或原生通知,因为这是用户刚
|
||
完成的显式操作,结果已经可见。
|
||
- 关闭总开关后宠物窗口和任何气泡立即消失;设置页本身不产生额外通知。
|
||
- 外观、位置相关 Switch 和滑块的变更立即生效并持久化,失败时通过应用通知报告,不静默
|
||
丢弃用户输入。
|
||
|
||
## 3. 托盘入口
|
||
|
||
- 托盘菜单在“新建对话”与“设置”之间新增一项,文案随当前可见性变化:
|
||
- 已启用且可见:“隐藏桌面宠物”。
|
||
- 已启用但隐藏:“显示桌面宠物”。
|
||
- 未启用:“显示桌面宠物”,点击后等同于在设置中开启总开关并显示窗口。
|
||
- 该菜单项不复制设置页的开关语义,只切换可见性;未启用状态下点击才会连带开启总开关,
|
||
行为需要在可访问名称或菜单说明中明确,避免用户误以为它只是显示/隐藏。
|
||
|
||
## 4. 宠物窗口
|
||
|
||
宠物窗口是无边框、透明背景、不可缩放的持久悬浮窗口,不使用 `PageShell`、不属于标准
|
||
一级页面,因此以下规则专属于该窗口:
|
||
|
||
```text
|
||
┌───────────┐
|
||
│ 角色 │ ← 状态镜面:角色外观随任务状态切换
|
||
│ (idle) │
|
||
└───────────┘
|
||
```
|
||
|
||
- 窗口本身没有标题栏、边框或系统窗口控件;关闭宠物只能通过设置总开关、托盘“隐藏桌面
|
||
宠物”或退出应用完成,窗口自身不提供关闭按钮,避免与“暂时隐藏”“关闭功能”两种含义
|
||
混淆。
|
||
- 窗口整体可拖动;拖动过程中显示当前吸附意图(开启贴边时,接近边缘会有轻微吸附反馈)。
|
||
- 窗口右键菜单提供“快速起草”“暂时隐藏”“打开设置”“退出 GoodBuddy”,与托盘菜单保持
|
||
同一套文案。
|
||
|
||
### 4.1 状态镜面外观
|
||
|
||
宠物角色在以下六种取值间切换,取值定义见[功能逻辑](./logic-design.md) 第 3 节:
|
||
|
||
| 状态 | 视觉表达 | 可访问名称 |
|
||
| --- | --- | --- |
|
||
| `unavailable` | 角色显示为暗淡的问号叠加 | “任务状态当前不可用” |
|
||
| `idle` | 角色静止或轻微待机动作 | “没有进行中的任务” |
|
||
| `running` | 角色显示持续的工作动作 | “有任务正在执行” |
|
||
| `waiting_approval` | 角色举牌或举手动作,带醒目但非警示色的强调 | “有任务等待你的确认” |
|
||
| `completed_recent` | 角色短暂展示完成动作后回到待机 | “有任务刚刚完成” |
|
||
| `failed_recent` | 角色显示明显区别于完成的姿态,并叠加警示色边缘 | “有任务失败,需要查看” |
|
||
|
||
- 状态表达必须同时使用动作/姿态和可访问名称两种信号,不能只依赖颜色区分
|
||
`completed_recent` 与 `failed_recent`。
|
||
- `prefers-reduced-motion` 或用户将动画强度设为“关闭”时,状态切换只改变静态姿态和颜色
|
||
强调,不播放位移或缩放动画。
|
||
- 点击状态镜面区域(角色本体)触发 US-D4:显示并聚焦主窗口,Task Center 定位到触发
|
||
当前状态的任务;`idle` 和 `unavailable` 状态下点击等同于显示并聚焦主窗口,不做定位。
|
||
|
||
### 4.2 快速起草弹出框
|
||
|
||
点击宠物打开的弹出框锚定在宠物窗口旁(自动避开屏幕边缘),结构如下:
|
||
|
||
```text
|
||
发送到:[当前会话名称 v]
|
||
|
||
[多行文本输入,占位文案“输入消息,或拖入文件…”]
|
||
|
||
[📎 附加文件] [已附加:contract.docx ×]
|
||
|
||
[取消] [提交]
|
||
```
|
||
|
||
- “发送到”是一个富信息单选菜单,选项为当前活跃会话与“新建对话”,遵循全局设计系统
|
||
第 6.11 节的单选选择器规则;默认选中当前活跃会话。
|
||
- 文本输入支持多行、`Ctrl+V` 粘贴图片和文字,与主窗口聊天输入框的粘贴行为一致。
|
||
- 附加文件按钮打开原生文件选择;已附加文件以行内标签形式展示,可单独移除。
|
||
- 拒绝的文件(超限或不支持)在附件区下方以就地错误文字展示,不使用应用级通知,因为
|
||
这是与当前操作直接绑定的字段级反馈。
|
||
- “提交”把文本和附件转交目标会话的输入区草稿,随后关闭弹出框;提交过程中禁用重复
|
||
点击并显示进行中状态,成功后不额外弹出通知(主窗口的显现和草稿本身就是反馈)。
|
||
- “取消”或点击弹出框外部或按 Escape 关闭弹出框并丢弃草稿,焦点返回宠物窗口。
|
||
- 弹出框打开时焦点进入文本输入;Tab 顺序为文本输入 → 附加文件 → 已附加文件的移除
|
||
按钮 → 取消 → 提交;关闭后焦点回到宠物窗口本体。
|
||
|
||
### 4.3 拖放反馈
|
||
|
||
- 文件或文字拖入宠物窗口范围时,窗口整体出现可放置的高亮边框和轻微放大反馈。
|
||
- 释放后立即按第 4.2 节“提交”的相同路径处理,不额外弹出确认框;这保持“拖动=起草并
|
||
发送到会话输入区(而非立即发送消息)”的一致语义。
|
||
- 拖入文件夹或全部文件超限时,宠物短暂显示拒绝反馈(边框变为警示色并伴随简短文字
|
||
提示,例如“不支持文件夹”),不打开主窗口、不产生暂存。
|
||
- 部分文件超限、部分合法时,合法文件正常处理,超限文件的名称通过一条会在数秒后自动
|
||
消失的就地提示列出,不使用应用级通知(拖放是即时操作,反馈应贴近操作发生的位置)。
|
||
|
||
### 4.4 完成 / 失败气泡
|
||
|
||
```text
|
||
┌─────────────────────────────┐
|
||
│ ✓ 已完成 │
|
||
│ 合同风险检查 │
|
||
│ [×] │
|
||
└─────────────────────────────┘
|
||
▲
|
||
(角色)
|
||
```
|
||
|
||
- 气泡锚定在宠物窗口旁,方向随宠物在屏幕上的位置自动避开边缘。
|
||
- 完成气泡在约 4.5 秒后自动消失,与全局应用通知的成功/信息时长一致;失败气泡保持可见
|
||
直到用户点击查看或点击关闭按钮。
|
||
- 气泡本体可点击,等同于点击状态镜面:显示并聚焦主窗口并定位到对应任务。
|
||
- 关闭按钮 `[×]` 有独立可访问名称(“关闭提示”),不与气泡主体的点击目标冲突:点击
|
||
关闭按钮只关闭气泡,不导航到主窗口。
|
||
- 气泡使用 `status`/polite 实时区域播报完成,失败气泡使用 `alert`/assertive,与全局
|
||
设计系统的通知语义保持一致,即使气泡本身不是应用通知视口的一部分。
|
||
|
||
## 5. 与应用通知视口的关系
|
||
|
||
- 宠物气泡是应用通知视口的窗口外等价物,只在主窗口不可见/未聚焦且安静模式关闭时出现;
|
||
同一事件不会同时进入应用通知视口和宠物气泡,具体归并规则见
|
||
[功能逻辑](./logic-design.md) 第 4 节。
|
||
- 快速起草和拖放产生的字段级错误(附件超限、不支持类型)始终就地展示在宠物窗口或弹出
|
||
框内,不进入应用通知视口,保持“就地错误”与“全局通知”分工一致。
|
||
|
||
## 6. 无障碍
|
||
|
||
- 状态镜面、气泡和弹出框内的所有交互元素都有持久可访问名称,不依赖占位文案代替标签。
|
||
- 宠物窗口可通过系统级窗口切换获得焦点;获得焦点后:
|
||
- 预期的激活键(例如 Enter 或 Space)打开快速起草弹出框。
|
||
- 弹出框内 Tab 顺序遵循第 4.2 节。
|
||
- Escape 关闭当前打开的弹出框或气泡,焦点回到宠物窗口本体。
|
||
- 状态镜面的状态变化通过 `status`/polite 实时区域播报简短说明,避免因动画本身无法被
|
||
屏幕阅读器感知而丢失信息;不对每次动画帧重复播报。
|
||
- 焦点环、危险色使用和触控目标尺寸遵循全局设计系统第 11 节的通用要求。
|
||
|
||
## 7. 响应式与多显示器
|
||
|
||
- 宠物窗口尺寸不随主窗口大小变化;用户通过设置中的“尺寸”滑块单独控制。
|
||
- 宠物窗口位置按显示器分别记忆;显示器不可用时的回退规则见
|
||
[功能逻辑](./logic-design.md) 第 7 节,界面表现为宠物出现在主显示器的默认可见位置,
|
||
不出现在屏幕之外或不可见状态。
|
||
- 弹出框和气泡的锚定方向根据宠物当前位置与屏幕边缘的距离自动选择展开方向(上/下/左/
|
||
右),确保始终完整可见,不被裁切到屏幕外。
|
||
|
||
## 8. 深浅主题
|
||
|
||
- 弹出框、气泡和设置页控件复用全局语义令牌,不新增页面专属颜色。
|
||
- 宠物角色素材本身分别提供适配浅色和深色桌面背景的版本,避免透明背景下角色轮廓在深色
|
||
桌面壁纸上难以辨认;具体资源交付方式属于技术设计范畴。
|
||
|
||
## 9. 固定词汇
|
||
|
||
使用“桌面宠物”“启用桌面宠物”“暂时隐藏”“快速起草”“安静模式”“状态镜面”,定义见
|
||
[README](./README.md) 术语表。不使用“挂件”“桌宠助手”或其他未在术语表中定义的别名,
|
||
保持中文文案统一。
|