Commit ef4cd62e authored by edy's avatar edy

fix(ui): refine reasoning strip indicator

parent d0943957
...@@ -215,7 +215,8 @@ export function MessageList({ ...@@ -215,7 +215,8 @@ export function MessageList({
const messageTrace = message.role === "assistant" ? messageTraces[message.id] : undefined const messageTrace = message.role === "assistant" ? messageTraces[message.id] : undefined
const hasTrace = Boolean(messageTrace?.items.length) const hasTrace = Boolean(messageTrace?.items.length)
const isTraceExpanded = Boolean(messageTrace?.expanded) const isTraceExpanded = Boolean(messageTrace?.expanded)
const showReasoningStrip = message.role === "assistant" && !videoStatusCard && (hasTrace || message.streamState === "error" || isWaitingForContent) const isReasoningActive = message.streamState === "streaming" || message.streamState === "error"
const showReasoningStrip = message.role === "assistant" && !videoStatusCard && isReasoningActive && (hasTrace || message.streamState === "error" || isWaitingForContent)
const traceDisplayLines = hasTrace ? getTraceDisplayLines(messageTrace?.items ?? []) : [] const traceDisplayLines = hasTrace ? getTraceDisplayLines(messageTrace?.items ?? []) : []
const traceTitle = getTraceStripTitle(messageTrace?.items ?? [], labels.thinking, message.statusLabel, message.statusDetail) const traceTitle = getTraceStripTitle(messageTrace?.items ?? [], labels.thinking, message.statusLabel, message.statusDetail)
const canCopyMessage = Boolean(message.content.trim()) const canCopyMessage = Boolean(message.content.trim())
...@@ -234,7 +235,13 @@ export function MessageList({ ...@@ -234,7 +235,13 @@ export function MessageList({
onClick={() => onTraceExpandedChange(message.id, !isTraceExpanded)} onClick={() => onTraceExpandedChange(message.id, !isTraceExpanded)}
aria-expanded={isTraceExpanded} aria-expanded={isTraceExpanded}
> >
<span className="reasoning-strip-leading" aria-hidden="true" /> <span className="reasoning-strip-leading" aria-hidden="true">
<span className="reasoning-strip-dots">
<span className="reasoning-strip-dot" />
<span className="reasoning-strip-dot" />
<span className="reasoning-strip-dot" />
</span>
</span>
<span className="reasoning-strip-title">{traceTitle}</span> <span className="reasoning-strip-title">{traceTitle}</span>
<span className="reasoning-strip-action">{isTraceExpanded ? labels.hideTrace : labels.traceCollapsed}</span> <span className="reasoning-strip-action">{isTraceExpanded ? labels.hideTrace : labels.traceCollapsed}</span>
</button> </button>
......
...@@ -246,7 +246,7 @@ ...@@ -246,7 +246,7 @@
width: min(100%, 880px); width: min(100%, 880px);
min-height: 32px; min-height: 32px;
display: grid; display: grid;
grid-template-columns: 14px minmax(0, 1fr) auto; grid-template-columns: 24px minmax(0, 1fr) auto;
justify-content: start; justify-content: start;
align-items: center; align-items: center;
gap: 7px; gap: 7px;
...@@ -281,9 +281,9 @@ ...@@ -281,9 +281,9 @@
.reasoning-strip.streaming { .reasoning-strip.streaming {
background: background:
linear-gradient(90deg, rgba(13, 148, 136, 0.11), rgba(37, 99, 235, 0.1), rgba(15, 23, 42, 0.045)); linear-gradient(90deg, rgba(13, 148, 136, 0.13), rgba(37, 99, 235, 0.12), rgba(15, 23, 42, 0.05));
color: #27506d; color: #1e4e68;
box-shadow: inset 0 0 0 1px rgba(59, 130, 246, 0.08); box-shadow: inset 0 0 0 1px rgba(59, 130, 246, 0.1);
} }
.reasoning-strip.streaming::after { .reasoning-strip.streaming::after {
...@@ -301,7 +301,7 @@ ...@@ -301,7 +301,7 @@
.reasoning-strip.streaming:hover, .reasoning-strip.streaming:hover,
.reasoning-strip.streaming.expanded { .reasoning-strip.streaming.expanded {
background: background:
linear-gradient(90deg, rgba(13, 148, 136, 0.14), rgba(37, 99, 235, 0.13), rgba(15, 23, 42, 0.055)); linear-gradient(90deg, rgba(13, 148, 136, 0.16), rgba(37, 99, 235, 0.15), rgba(15, 23, 42, 0.06));
} }
.reasoning-strip.error { .reasoning-strip.error {
...@@ -310,30 +310,44 @@ ...@@ -310,30 +310,44 @@
} }
.reasoning-strip-leading { .reasoning-strip-leading {
width: 14px; width: 24px;
height: 14px; height: 14px;
display: grid; display: grid;
place-items: center; place-items: center;
} }
.reasoning-strip-leading::before { .reasoning-strip-dots {
content: ""; display: inline-flex;
width: 5px; align-items: center;
height: 5px; justify-content: center;
gap: 3px;
}
.reasoning-strip-dot {
width: 4px;
height: 4px;
border-radius: var(--radius-full); border-radius: var(--radius-full);
background: #64748b; background: #64748b;
box-shadow: 0 0 0 3px rgba(100, 116, 139, 0.12); box-shadow: 0 0 0 2px rgba(100, 116, 139, 0.1);
} }
.reasoning-strip.streaming .reasoning-strip-leading::before { .reasoning-strip.streaming .reasoning-strip-dot {
background: #0d9488; background: #0d9488;
box-shadow: 0 0 0 3px rgba(13, 148, 136, 0.13); box-shadow: 0 0 0 2px rgba(13, 148, 136, 0.14);
animation: trace-status-pulse 1.5s ease-in-out infinite; animation: trace-dot-bounce 1.25s ease-in-out infinite;
}
.reasoning-strip.streaming .reasoning-strip-dot:nth-child(2) {
animation-delay: 140ms;
}
.reasoning-strip.streaming .reasoning-strip-dot:nth-child(3) {
animation-delay: 280ms;
} }
.reasoning-strip.error .reasoning-strip-leading::before { .reasoning-strip.error .reasoning-strip-dot {
background: #ef4444; background: #ef4444;
box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.12); box-shadow: 0 0 0 2px rgba(239, 68, 68, 0.12);
} }
.reasoning-strip-title, .reasoning-strip-title,
...@@ -352,7 +366,7 @@ ...@@ -352,7 +366,7 @@
} }
.reasoning-strip.streaming .reasoning-strip-title { .reasoning-strip.streaming .reasoning-strip-title {
background: linear-gradient(90deg, #0f766e, #2563eb, #334155); background: linear-gradient(90deg, #0f766e, #1d4ed8, #1f3a5f);
background-size: 180% 100%; background-size: 180% 100%;
-webkit-background-clip: text; -webkit-background-clip: text;
background-clip: text; background-clip: text;
...@@ -1131,14 +1145,14 @@ select:focus-visible { ...@@ -1131,14 +1145,14 @@ select:focus-visible {
} }
} }
@keyframes trace-status-pulse { @keyframes trace-dot-bounce {
0%, 100% { 0%, 100% {
opacity: 0.62; opacity: 0.48;
transform: scale(0.92); transform: translateY(0) scale(0.9);
} }
50% { 50% {
opacity: 1; opacity: 1;
transform: scale(1.18); transform: translateY(-3px) scale(1.08);
} }
} }
...@@ -1153,7 +1167,7 @@ select:focus-visible { ...@@ -1153,7 +1167,7 @@ select:focus-visible {
@media (prefers-reduced-motion: reduce) { @media (prefers-reduced-motion: reduce) {
.reasoning-strip.streaming::after, .reasoning-strip.streaming::after,
.reasoning-strip.streaming .reasoning-strip-leading::before, .reasoning-strip.streaming .reasoning-strip-dot,
.reasoning-strip.streaming .reasoning-strip-title { .reasoning-strip.streaming .reasoning-strip-title {
animation: none; animation: none;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment