优化: P1-a 长内容折叠(AI文本气泡+多冲突+错误堆栈)
- MessageList: assistant文本气泡>1500字符折叠(max-height 400px+渐变遮罩+展开按钮),流式中不折叠避免delta重排抖动(M1) - ConflictResolver: 多冲突(>=3)默认折叠,点击展开diff(M6) - HelpRequiredCard: context堆栈max-height 200px滚动+等宽字体(M7)
This commit is contained in:
@@ -548,6 +548,31 @@ function toggleSegment(key: string): void {
|
||||
expandedSegmentIds.value = next
|
||||
}
|
||||
|
||||
// M1:assistant 纯文本气泡超长折叠,避免单条 AI 回复撑爆对话区。
|
||||
// 仅对「已完成(非流式)」assistant 文本生效;流式中的消息不折叠(delta 重排抖动)。
|
||||
// 阈值 1500 字符:约 markdown 渲染后一屏(400px@13px/1.6≈35行)的源文本量,超此即判长。
|
||||
// 折叠 max-height 同步 400px(见 CSS .ai-msg-bubble--collapsed,两处一致)。
|
||||
const LONG_MSG_THRESHOLD = 1500
|
||||
/// 展开的长消息 id 集合(点击底部按钮切换);默认折叠
|
||||
const expandedLongIds = ref<Set<string>>(new Set())
|
||||
function toggleLong(id: string): void {
|
||||
const next = new Set(expandedLongIds.value)
|
||||
if (next.has(id)) next.delete(id)
|
||||
else next.add(id)
|
||||
expandedLongIds.value = next
|
||||
}
|
||||
function isLongMsg(msg: AiMessage): boolean {
|
||||
return msg.role === 'assistant' && !!msg.content && msg.content.length > LONG_MSG_THRESHOLD
|
||||
}
|
||||
/// 是否折叠展示该 assistant 文本气泡:长消息 + 未手动展开 + 非流式(当前未在流式生成)。
|
||||
function shouldCollapseLong(msg: AiMessage): boolean {
|
||||
if (!isLongMsg(msg)) return false
|
||||
if (expandedLongIds.value.has(msg.id)) return false
|
||||
// 流式约束:正在生成的当前消息不折叠(避免 delta 重排抖动),参考 L92 同款 streaming 判定。
|
||||
if (isLastAi(msg) && store.state.streaming) return false
|
||||
return true
|
||||
}
|
||||
|
||||
type RenderItem =
|
||||
| { kind: 'msg'; key: string; msg: AiMessage }
|
||||
| { kind: 'sep'; key: string; seg: MessageSegment & { key: string } }
|
||||
@@ -683,7 +708,7 @@ defineExpose({
|
||||
<div
|
||||
v-if="item.msg.content || (isLastAi(item.msg) && store.state.streaming && store.state.currentText)"
|
||||
class="ai-msg-bubble ai-msg-bubble--ai ai-md"
|
||||
:class="{ 'ai-msg-bubble--error': item.msg.isError }"
|
||||
:class="{ 'ai-msg-bubble--error': item.msg.isError, 'ai-msg-bubble--collapsed': shouldCollapseLong(item.msg) }"
|
||||
:key="'md-' + item.msg.id + '-' + (isLastAi(item.msg) ? _mdRenderKey : 0)"
|
||||
>
|
||||
<!-- 流式:分块渲染(已完成块key稳定→DOM不重建) -->
|
||||
@@ -693,6 +718,12 @@ defineExpose({
|
||||
</template>
|
||||
<!-- 完成/历史:整段v-html(不变) -->
|
||||
<div v-else v-html="renderMd(item.msg.content)"></div>
|
||||
<!-- M1:超长 assistant 文本折叠后的底部展开按钮(仅非流式 + 长消息显示) -->
|
||||
<button
|
||||
v-if="isLongMsg(item.msg) && !(isLastAi(item.msg) && store.state.streaming)"
|
||||
class="ai-msg-bubble-toggle"
|
||||
@click.stop="toggleLong(item.msg.id)"
|
||||
>{{ expandedLongIds.has(item.msg.id) ? $t('aiChat.collapse') : $t('aiChat.expand') }}</button>
|
||||
<button
|
||||
v-if="item.msg.content"
|
||||
class="ai-copy-btn ai-copy-btn--ai"
|
||||
@@ -895,6 +926,44 @@ defineExpose({
|
||||
.ai-msg-bubble--ai.ai-md {
|
||||
overflow-x: auto;
|
||||
}
|
||||
/* M1:超长 assistant 文本折叠——max-height 截断 + 底部渐变遮罩 + 展开按钮。
|
||||
背景 var(--df-bg-card) 对齐 .ai-msg-bubble--ai(L876):渐变淡出到气泡背景,
|
||||
视觉上内容「沉入」气泡而非被硬切。overflow:hidden 覆盖 .ai-md 的 overflow-x:auto。 */
|
||||
.ai-msg-bubble--collapsed {
|
||||
max-height: 400px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
.ai-msg-bubble--collapsed::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 48px;
|
||||
background: linear-gradient(transparent, var(--df-bg-card));
|
||||
pointer-events: none; /* 让点击穿透到下方展开按钮 */
|
||||
}
|
||||
/* 展开按钮:气泡底部居中,置于渐变遮罩之上 */
|
||||
.ai-msg-bubble-toggle {
|
||||
position: absolute;
|
||||
bottom: 6px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
z-index: 1;
|
||||
padding: 2px 12px;
|
||||
font-size: 11px;
|
||||
line-height: 1.4;
|
||||
color: var(--df-accent);
|
||||
background: var(--df-bg-card);
|
||||
border: 0.5px solid var(--df-border);
|
||||
border-radius: var(--df-radius);
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
.ai-msg-bubble-toggle:hover {
|
||||
background: var(--df-bg-card-hover);
|
||||
}
|
||||
|
||||
/* ── Input Augmentation: 用户气泡内 mention chip(圆角徽标,复用 ChatInput .ai-skill-chip-name 风格) ──
|
||||
用户气泡背景 = --df-accent(主题强调色,如深色蓝/紫),chip 用半透明白底+深字 保证对比度;
|
||||
|
||||
Reference in New Issue
Block a user