进度 HUD
一个长任务:身体说正在发生什么,外环说进行到哪一步。
先看效果
一个向仲裁器报告比例的会话。AgentHud 从同一个结果里读出状态、表盘和提示,三者不可能在描述不同的任务。到达终点时发送 celebrate,这是仲裁器永不丢弃的事件。
滑块移动之前仲裁器什么都没听到,所以 AgentHud 画的是一个没有表盘的空闲角色——HUD 是页面上的装饰,页面在任何智能体连上之前就得先渲染出来。useHudSpec('progress', { value }) 给手工组装 spec 的宿主同样的保护:首次渲染时还是 undefined 的比例会变成 null,而 hud={null} 就是一个没有表盘的角色。
什么时候用
一个长任务——导出、建索引、一批上传——旁边站着一个整段时间都有东西可展示的角色。两层各司其职。身体说明智能体在做什么:working,或者当任务是可度量的东西时用 progress。身体外侧的环说明它知道什么:一个比例、一个上限、一个同步状态。两者有意分开,所以一个角色可以一边工作一边显示 83%,而不会为同一块像素争抢。
用到的组件
CharacterMark——hud={...},一个宿主已经掌握数据的HudSpec。HudPlate——把数字作为文字放在表盘旁边,在一个 polite 的实时区域里,因为环说不出"83%"。AgentHud——把仲裁器当前的状态、表盘和说明合成一个组件,一个会话的表盘不可能站在另一个会话的脸旁边。useHudSpec——用实时数值构造 spec,数值还站不住时得到null。AgentStateProvider——数字到达的地方。
状态怎么走
progress 状态的腰带是不定长的:一个以四秒为周期填满再重置的环,意思是"一件可度量的事正在进行"。度量值本身始终放在 HUD 里,HUD 的 progress 环才是那个数值。比例重要时用 working 的身体配 progress 表盘;只能说"它在动"时用 progress 的身体。
每个状态的样子
| 状态 | 眼睛 | 嘴 | 特效 | 编号 | HUD | |
|---|---|---|---|---|---|---|
working工作 | dotDown → dot → dotDown | none | arc | 1632 | gauge | |
progress进度 | dot | none | progress | 47 | progress | |
uploading上传 | dotUp → dot | none | rise | 45 | sync | |
loading加载 | dot → dotLook | none | spinner | 0536 | — | |
celebrate庆祝 | star → archWide → wink → arch | grin | sparkle | 2533 | kpi | |
alerting警示 | dotWide → dot | o | bang | 34 | — |
在 eyes 和 line 脸下,其中四个把身体交给了腰带。由于 HUD 画在身体外侧的环里,腰带状态和表盘可以共存:身体收缩成核心,腰带围着它转,表盘在更外面一圈。
六种表盘
给可度量事物的六种表盘。progress 与 gauge 是相对上限的比例;context 数格子而不是填弧线,因为最后几个格子才是要紧的;balance 只表现量级,数字留给 plate;kpi 把一组序列画成折线;sync 是一个生命周期。每一种都是 (spec, time) 的纯函数,所以暂停的角色、服务端渲染和截图三者一致。