Skip to content

feat: per-turn file change summary button - #1851

Open
ArrogHie wants to merge 1 commit into
GCWing:mainfrom
ArrogHie:feature/turn-files-summary
Open

feat: per-turn file change summary button#1851
ArrogHie wants to merge 1 commit into
GCWing:mainfrom
ArrogHie:feature/turn-files-summary

Conversation

@ArrogHie

Copy link
Copy Markdown
Contributor

概述

新增 TurnFilesSummary 组件,在最后一轮对话完成后,于会话下方渲染一个居中且醒目的按钮。按钮显示该轮对话中修改的文件个数以及总增删行数。点击按钮展开浮层,列出所有被修改的文件;点击文件可打开 diff 编辑器查看具体改动。

现有的 SessionFilesBadge 位于聊天头部,显示整个会话中修改的所有文件。本功能提供按轮次粒度的改动展示,仅在轮次完全结束(包括打字机动画)后出现,并在新一轮对话开始时自动消失。


核心行为

  • 仅在最后一轮对话的最后一个 round 上渲染(isLastRoundisLastTurn
  • 等待流式输出和打字机动画全部结束后才出现(!isVisuallyStreaming
  • 新一轮对话开始时自动消失(isLastTurn 变为 false
  • 使用 get_turn_files Rust 命令按轮次范围获取文件(非全会话)
  • 按钮居中显示,与底部操作栏(复制/导出/Fork)分离
  • 浮层弹出动画直接居中定位,无先右后中的跳变
  • 所有 hooks 在任何提前返回之前统一调用(无 "rendered more hooks" 错误)

变更文件

状态 文件 改动
新增 TurnFilesSummary.tsx +465
新增 TurnFilesSummary.scss +261
修改 ModelRoundItem.tsx +13 −3
修改 SnapshotAPI.ts +20
修改 modernFlowChatStore.ts +5
修改 VirtualItemRenderer.tsx +2
修改 en-US/flow-chat.json +5
修改 zh-CN/flow-chat.json +5
修改 zh-TW/flow-chat.json +5

数据流

DialogTurn.backendTurnIndex
  → sessionToVirtualItems()
  → VirtualItem (turnBackendIndex, isLastTurn)
  → VirtualItemRenderer
  → ModelRoundItem (turnBackendIndex, isLastTurn)
  → 条件挂载 TurnFilesSummary (sessionId, turnIndex)
  → snapshotAPI.getTurnFiles(sessionId, turnIndex) → Rust get_turn_files
  → snapshotAPI.getSessionFileDiffStats(sessionId, filePath) → diff 统计

实现细节

TurnFilesSummary.tsx(新增,465 行)
自包含组件:通过 getTurnFiles 加载该轮文件,以 60 秒 TTL 缓存和并发上限 3 获取每个文件的 diff 统计,渲染居中按钮和浮层。点击文件通过 createDiffEditorTab 打开 diff 编辑器。

TurnFilesSummary.scss(新增,261 行)
全宽 flex 容器,按钮居中。按钮:28px 高度,sm 字号,柔和背景色,细边框。浮层:通过 left:50% + translateX(-50%) 居中,动画关键帧保留 translateX 避免位置跳变。

ModelRoundItem.tsx(+13 −3)
新增 isLastTurn prop。TurnFilesSummary 渲染在 footer div 外部(独立视觉区块)。渲染条件:isTurnComplete && isLastRound && isLastTurn && !isVisuallyStreaming。memo 比较函数加入 isLastTurn

SnapshotAPI.ts(+20)
新增 getTurnFiles(sessionId, turnIndex, workspacePath?) 方法,封装已有的 Rust get_turn_files 命令,带请求去重。

modernFlowChatStore.ts(+5)
model-round VirtualItem 类型中新增 isLastTurnturnBackendIndex 字段。分别从 turnIndex === dialogTurns.length - 1turn.backendTurnIndex 赋值。

国际化(3 个语言文件共 +15)
新增 turnFilesSummary 命名空间,包含 filesCountexpandCueclickToViewDiff 三个键,覆盖 en-US、zh-CN、zh-TW。


开发中解决的问题

1. "Rendered more hooks than during the previous render"
toggleHintuseMemo 放在了提前 return null 之后。将所有 hooks 移到任何条件返回之前,确保 hook 数量在每次渲染中恒定。

2. 浮层弹出时位置跳变
动画关键帧仅包含 translateY,丢失了 translateX(-50%) 居中偏移。在 fromto 关键帧中均加入 translateX(-50%),使动画全程保持居中。

3. Agent 输出时屏闪
TurnFilesSummary 在流式输出期间提前出现,导致虚拟列表高度变化引起重排。通过增加 !isVisuallyStreaming 条件和容器 min-height:0 修复。


验证

检查项 结果
pnpm run type-check:web(tsc --noEmit) 通过
pnpm run i18n:contract:test(37 项测试) 通过

Add a TurnFilesSummary component that shows a centered button with file
count and line changes for the last completed turn only. Clicking the
button expands a popover listing all files modified in that turn, each
openable in a diff editor.

- Only renders on the last round of the last turn after streaming ends
- Disappears when a new turn starts (isLastTurn becomes false)
- Uses get_turn_files Rust command for per-turn file scoping
- Add getTurnFiles to SnapshotAPI with dedup
- Add isLastTurn and turnBackendIndex to VirtualItem model-round
- Add i18n keys for en-US, zh-CN, zh-TW
@ArrogHie
ArrogHie force-pushed the feature/turn-files-summary branch from 64f7201 to 43436b2 Compare July 30, 2026 01:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant