Conversation
…nd sidebar UX - ChatLayout: when preview open, header row full-width; when closed, header stays in chat column (workspace can squeeze it). Reuse headerBlock to minimize duplication. - Model selectors: compact style (max-width + truncate) when preview panel is open (GeminiModelSelector, AcpModelSelector). - PreviewToolbar: smaller height and padding, brand color for selected state (tabs and buttons), refined button styles. - WorkspaceGroupedHistory: selected item text-1, unselected text-2, hover text-1. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Code Review
HIGH Issues
1. AcpModelSelector 新增 console.error(生产调试卫生)
File: src/renderer/components/AcpModelSelector.tsx:74-78
.catch((error) => {
console.error('[AcpModelSelector] Failed to set model:', error);
});Problem: 项目 ESLint 规则 no-console: warn 明确要求避免在生产代码中新增 console.log/console.*。这里是本 PR 新增的 console.error,会在正常用户操作(切换模型失败、IPC 异常)时直接输出到控制台,属于明确的“新增 console”问题,应该按规范处理(统一日志通道/上报/用户提示)。
Fix: 用项目既有的日志/提示机制替代。比如(示例):
.catch((error) => {
// 1) 统一 logger(若项目有)
logger.error('[AcpModelSelector] Failed to set model', { error });
// 或 2) 给用户提示(更符合 UX)
Message.error(t('conversation.modelSwitchFailed'));
});如果确实需要保留控制台输出,建议至少用 __DEV__/环境开关包裹,避免生产环境噪音。
MEDIUM Issues
2. ChatLayout 在 useHeaderFullWidth 分支中:预览拖拽手柄无条件渲染,可能导致“预览关闭也可拖拽/布局异常”
File: src/renderer/pages/conversation/ChatLayout.tsx:338-346
<div className='flex flex-col relative' style={{ flexGrow: 0, flexShrink: 0, flexBasis: `${chatFlex}%`, minWidth: '240px' }} ...>
<ArcoLayout.Content className='flex flex-col flex-1 bg-1 overflow-hidden'>{props.children}</ArcoLayout.Content>
{createPreviewDragHandle({ className: 'absolute right-0 top-0 bottom-0', style: {} })}
</div>Problem: 旧逻辑里预览拖拽手柄是受条件控制的(isPreviewOpen && !layout?.isMobile)。新分支 useHeaderFullWidth 虽然由 isPreviewOpen && isDesktop 推导,理论上成立,但这里把“是否渲染拖拽手柄”的业务条件隐含在外层分支里,后续如果 useHeaderFullWidth 条件被调整(例如未来允许移动端/或预览打开但不显示预览面板的状态),会非常容易引入“手柄仍存在但预览不存在”的 UI/交互 bug。
Fix: 保持条件显式,降低未来改动风险:
{isPreviewOpen && !layout?.isMobile && createPreviewDragHandle(...)}即使当前逻辑等价,也建议显式表达“手柄只在预览打开且非移动端出现”。
3. GeminiModelSelector 仅对 enabled/header 做 compact,disabled/header 未同步,导致预览打开时按钮宽度策略不一致
File: src/renderer/pages/conversation/gemini/GeminiModelSelector.tsx:20-38
if (disabled || !selection) {
...
return (
<Tooltip ...>
<Button className='sendbox-model-btn header-model-btn' shape='round' size='small' style={{ cursor: 'default' }}>
{displayLabel}
</Button>
</Tooltip>
);
}
...
<Button className={classNames('sendbox-model-btn header-model-btn', compact && '!max-w-[120px]')} ...>
<span className={compact ? 'block truncate' : undefined}>{label}</span>
</Button>Problem: 你在 PR 描述里强调“预览打开时紧凑样式(max-w + truncate)”,但 Gemini selector 的 disabled 分支仍然是原始按钮(无 max-w、无 truncate)。这会造成同一位置在不同状态(可用/不可用)下宽度表现不一致,尤其是预览打开时更容易出现 header 被撑开/抖动。
Fix: disabled/header 分支也复用同一套 compact 逻辑:
<Button
className={classNames('sendbox-model-btn header-model-btn', compact && '!max-w-[120px]')}
...
>
<span className={compact ? 'block truncate' : undefined}>{displayLabel}</span>
</Button>Summary
| Level | Count |
|---|---|
| CRITICAL | 0 |
| HIGH | 1 |
| MEDIUM | 2 |
🤖 This review was generated by AI and may contain inaccuracies. Please focus on issues you agree with and feel free to disregard any that seem incorrect. Thank you for your contribution!
Note: The following inputs were truncated due to size limits: file contents (>80K chars).
Please review the omitted portions manually.
…collapse button - Markdown CodeBlock: default to collapsed; minWidth/maxWidth/overflowX so block does not expand layout when preview open; add collapse button at bottom when expanded. - MessageList/MessagetText: add min-w-0 so message content shrinks in narrow column, keep code block and bottom button visible. Co-authored-by: Cursor <cursoragent@cursor.com>
- ChatLayout: preview panel top margin 12px->6px; overflow-hidden for rounded clip; both preview divs. - PreviewTabs: tab bar height 40px->36px, padding and collapse icon slightly reduced. Co-authored-by: Cursor <cursoragent@cursor.com>
The disabled branch of GeminiModelSelector was missing the compact width constraint and text truncation that the enabled branch already had, causing inconsistent button widths when the preview panel is open.
概述
本 PR 对对话页的布局、预览面板工具栏和侧边栏对话列表做了体验优化:预览打开时标题栏不再被挤压、模型选择器与工具栏更紧凑统一、选中态统一为 AOU 品牌色、侧边栏选中/未选中与 hover 文字层级更清晰。
修改说明
1. 对话页布局(ChatLayout)
headerBlock复用标题栏 DOM,用useHeaderFullWidth = isPreviewOpen && isDesktop切换两种布局,减少重复代码和冲突面。2. 模型选择器(预览打开时紧凑)
max-w-[120px]+ 文案 truncate)。max-w-[120px]+ truncate)。3. 预览面板工具栏(PreviewToolbar)
px-8 py-3、text-12px、图标 12px,圆角rd-4px。text-brand、bg-aou-2、border-b-4 border-brand。bg-brand、白字,hoverbg-brand-hover。text-t-secondary,hovertext-t-primary+bg-bg-3,过渡duration-150。4. 侧边栏对话列表(WorkspaceGroupedHistory)
text-1+font-medium。text-2。group-hover:text-1,hover 时与选中一致为 text-1。5. 其他
WorkspacePanelHeader的togglePlacement='right'>曾导致 TS 解析问题,改为togglePlacement="right"。涉及文件
src/renderer/pages/conversation/ChatLayout.tsxsrc/renderer/pages/conversation/gemini/GeminiModelSelector.tsxsrc/renderer/components/AcpModelSelector.tsxsrc/renderer/pages/conversation/preview/components/PreviewPanel/PreviewToolbar.tsxsrc/renderer/pages/conversation/WorkspaceGroupedHistory.tsx