文档:换会话时复位 DirectProject 滚动所有权
- ADR 新增第 6 条:会话身份作为显式信号复位跟随最新/锚点/胶囊状态,并记录「key 重建列表」的取舍 - 决策记录追加换会话复位的症状、决策与验证口径 Co-authored-by: Junie <junie@jetbrains.com>
This commit is contained in:
@@ -52,6 +52,12 @@ DirectProject 聊天区(`apps/ai-game-creator-shell/src/view/project-developme
|
||||
- 控制器对渲染层暴露可渲染的 `historyLoading` 与 `historyError`(外加 `retryEarlierHistory`),取代只存在于 ref 里的加载标志。
|
||||
- 新增元素全部用内联 Tailwind 工具类,不改 `styles.css`;列表本身仍保持 `message-list project-chat-message-list` 类名不变,只追加 `overflow-anchor` 工具类。
|
||||
|
||||
### 6. 换会话时复位滚动所有权
|
||||
|
||||
- 列表容器在切项目时**不会重挂载**:`DirectProjectChatView` 在 `App.tsx` 只有一处渲染、没有 `key`,内部的 `DirectProjectConversation` 也没有 `key`,而 `useConversationScroll` 的跟随最新 / `atBottom` / `hasNewReply` / 前插锚点 / 折叠头 / 程序化滚动标记只在挂载时初始化一次。控制器自己按项目重置了历史状态,滚动所有权却一直漏着。
|
||||
- 症状:在项目 A 往上滚过再切到 B——① B 的首屏不贴底,用户得自己往下滚;② B 的第一批回合会在「不跟随」分支被算成新内容,胶囊在新项目上直接显示「有新回复 · 回到底部」,可用户根本没在 B 里离开过底部。
|
||||
- 决策:把会话身份(`conversationKey`,DirectProject 传项目路径)作为**显式信号**传给 `useConversationScroll`;身份变化时复位上述滚动所有权状态、把终态指纹同步成新会话内容、再贴底。不改变组件生命周期,同一个项目重开(身份不变)也不会被当成新会话;将来策划对话复用同一个 hook 时用的是同一套信号。
|
||||
|
||||
## 备选方案与取舍
|
||||
|
||||
1. **保留按钮 + 只加自动加载**:加载中仍靠按钮做唯一反馈,且删掉按钮后失败路径没有补救入口;按钮本身与滚动自动加载重复。
|
||||
@@ -60,11 +66,12 @@ DirectProject 聊天区(`apps/ai-game-creator-shell/src/view/project-developme
|
||||
4. **展开后总是把正文滚进视口**:对正文比视口矮的折叠块会把画面大幅上移,打断正在读历史的用户;采用「跟随时贴底 / 否则冻结折叠头 + 只滚到刚好露出新展开正文的最小位移」。
|
||||
5. **平滑滚动期间照常处理滚动事件与布局补偿**:程序化滚动会被应用自己的补偿打断(第一次写 `scrollTop` 即取消动画),用户点了「回到底部」也停在半路;因此改为滚动期间冻结这两条路径。
|
||||
6. **自动重试失败的历史加载**:弱网下会反复打接口,且用户看不出到底在重试还是在挂起;改为挂起 + 内联重试行。
|
||||
7. **用 `key={projectPath}` 让 React 重建会话列表**:改动最小,但整份消息列表连同加载行的 150ms 延迟计时一起重建,而且「同一个项目重开」也会被当成新会话;改用显式身份信号复位,重建与否与「换没换会话」解耦。
|
||||
|
||||
## 影响
|
||||
|
||||
- 历史加载失败不再只写顶部状态行,而是落到列表里的内联错误行;顶部状态行仍保留首屏读取失败等其它用途。
|
||||
- 滚动是表现层行为,正式状态仍在后端投影与运行态事件;本 ADR 不新增领域概念。
|
||||
- 阈值(触顶 24px、贴底 48px、spinner 150ms)是可按手感调整的常量,集中放在 `components/DirectProjectConversation/conversationScrollPolicy.ts`。
|
||||
- 验收:纯函数与 jsdom 组件测试覆盖阈值、锚点还原、加载/错误行、胶囊文案与显隐;滚动观感(顶部加载圈、胶囊出现与消失、底部展开回贴、历史前插不跳)必须真机手动验收——jsdom 没有布局。
|
||||
- 验收:纯函数与 jsdom 组件测试覆盖阈值、锚点还原、加载/错误行、胶囊文案与显隐;滚动观感(顶部加载圈、胶囊出现与消失、底部展开回贴、历史前插不跳、切项目后首屏贴底且不误报「有新回复」)必须真机手动验收——jsdom 没有布局。
|
||||
- 明确的后续项(不在本次范围):`PlanningChatView` 与 `App.tsx` 遗留 `message-history-more` 路径的同款改造、未读条数徽标、Playwright 端到端。
|
||||
|
||||
Reference in New Issue
Block a user