mirror of
https://github.com/hellodigua/ChatLab.git
synced 2026-10-25 17:54:34 +08:00
fix(ai): keep failed process visible and scope chat prose
Completed error segments stay expanded with a failed label, and the 16px reading size applies only to full-size chat answers so compact markdown previews keep their own sizing.
This commit is contained in:
1 parent
4eb522f3f6
commit
dd2d5dd39f
2 files changed
+52
-25
No files matched your search
@@ -4,11 +4,6 @@
|
||||
* 使用方式:在组件的 <style> 中 @import 此文件,或在全局样式中引入
|
||||
*/
|
||||
|
||||
.prose {
|
||||
font-size: 16px;
|
||||
line-height: 28px;
|
||||
}
|
||||
|
||||
/* 段落(全局样式不使用 :deep) */
|
||||
.prose p {
|
||||
margin: 12px 0;
|
||||
@@ -25,24 +20,24 @@
|
||||
|
||||
/* 标题 */
|
||||
.prose h1 {
|
||||
font-size: 24px;
|
||||
font-size: 1.25rem;
|
||||
font-weight: 700;
|
||||
margin: 24px 0 12px;
|
||||
line-height: 34px;
|
||||
margin: 1em 0 0.5em;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.prose h2 {
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
margin: 24px 0 12px;
|
||||
line-height: 32px;
|
||||
font-size: 1.125rem;
|
||||
font-weight: 600;
|
||||
margin: 0.875em 0 0.5em;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.prose h3 {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
margin: 24px 0 12px;
|
||||
line-height: 30px;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
margin: 0.75em 0 0.375em;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.prose h4,
|
||||
@@ -242,3 +237,30 @@
|
||||
.prose-invert blockquote p {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
/* 聊天正文的阅读字号,避免全局覆盖 prose-sm / text-xs */
|
||||
.ai-chat-prose {
|
||||
font-size: 16px;
|
||||
line-height: 28px;
|
||||
}
|
||||
|
||||
.ai-chat-prose h1 {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
margin: 24px 0 12px;
|
||||
line-height: 34px;
|
||||
}
|
||||
|
||||
.ai-chat-prose h2 {
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
margin: 24px 0 12px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
.ai-chat-prose h3 {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
margin: 24px 0 12px;
|
||||
line-height: 30px;
|
||||
}
|
||||
@@ -265,10 +265,7 @@ function isProcessSegmentOpen(segmentIndex: number): boolean {
|
||||
const key = getProcessSegmentKey(segmentIndex)
|
||||
const override = processSegmentOpenOverrides.value[key]
|
||||
if (override !== undefined) return override
|
||||
return (
|
||||
!isCompletedProcessSummary(renderSegments.value[segmentIndex]) &&
|
||||
hasProcessSegmentError(renderSegments.value[segmentIndex])
|
||||
)
|
||||
return hasProcessSegmentError(renderSegments.value[segmentIndex])
|
||||
}
|
||||
|
||||
function toggleProcessSegment(segmentIndex: number): void {
|
||||
@@ -354,6 +351,7 @@ function getProcessHeaderActivity(segment: ProcessSegment<ContentBlock>, segment
|
||||
|
||||
function getProcessHeaderTitle(segment: ProcessSegment<ContentBlock>, segmentIndex: number): string {
|
||||
if (isCompletedProcessSummary(segment)) {
|
||||
if (hasProcessSegmentError(segment)) return t('ai.chat.message.process.failed')
|
||||
return t('ai.chat.message.process.duration', {
|
||||
duration: formatProcessDuration(processElapsedMs.value, locale.value),
|
||||
})
|
||||
@@ -867,7 +865,7 @@ async function handleCopyMarkdown() {
|
||||
@click="toggleProcessSegment(segmentIdx)"
|
||||
>
|
||||
<span
|
||||
v-if="!isCompletedProcessSummary(segment)"
|
||||
v-if="!isCompletedProcessSummary(segment) || hasProcessSegmentError(segment)"
|
||||
class="relative mr-1.5 flex h-4 w-4 shrink-0 items-center justify-center"
|
||||
>
|
||||
<UIcon
|
||||
@@ -887,11 +885,18 @@ async function handleCopyMarkdown() {
|
||||
/>
|
||||
</template>
|
||||
</span>
|
||||
<span class="shrink-0 text-gray-600 dark:text-gray-300">
|
||||
<span
|
||||
class="shrink-0"
|
||||
:class="
|
||||
hasProcessSegmentError(segment)
|
||||
? 'text-amber-700 dark:text-amber-300'
|
||||
: 'text-gray-600 dark:text-gray-300'
|
||||
"
|
||||
>
|
||||
{{ getProcessHeaderTitle(segment, segmentIdx) }}
|
||||
</span>
|
||||
<UIcon
|
||||
v-if="isCompletedProcessSummary(segment)"
|
||||
v-if="isCompletedProcessSummary(segment) && !hasProcessSegmentError(segment)"
|
||||
:name="isProcessSegmentOpen(segmentIdx) ? 'i-heroicons-chevron-down' : 'i-heroicons-chevron-right'"
|
||||
class="ml-1 h-3.5 w-3.5 shrink-0 text-gray-500 dark:text-gray-400"
|
||||
/>
|
||||
@@ -958,7 +963,7 @@ async function handleCopyMarkdown() {
|
||||
:class="[
|
||||
segment.type === 'process' && !isCompletedProcessSummary(segment)
|
||||
? 'prose-sm leading-relaxed'
|
||||
: '',
|
||||
: 'ai-chat-prose',
|
||||
]"
|
||||
v-html="renderMarkdown(getDisplayText(block.text))"
|
||||
/>
|
||||
@@ -1313,7 +1318,7 @@ async function handleCopyMarkdown() {
|
||||
<!-- AI 消息:传统纯文本渲染(向后兼容) -->
|
||||
<template v-else>
|
||||
<div class="py-1 text-gray-900 dark:text-gray-100">
|
||||
<div class="prose dark:prose-invert max-w-none" v-html="renderedContent" />
|
||||
<div class="prose ai-chat-prose dark:prose-invert max-w-none" v-html="renderedContent" />
|
||||
<span
|
||||
v-if="isStreaming"
|
||||
class="ml-1 inline-block h-4 w-1.5 animate-pulse rounded-sm bg-gray-800 dark:bg-gray-200"
|
||||
|
||||
Reference in new issue
Block a user