From c584508b949354d59ae321469ceae1414f7adcf6 Mon Sep 17 00:00:00 2001 From: Rick Ye Date: Tue, 8 Sep 2026 00:34:52 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=80=9D=E8=80=83=E5=B1=95=E5=BC=80?= =?UTF-8?q?=E6=81=A2=E5=A4=8D=E5=AE=8C=E6=95=B4=E5=B1=95=E7=A4=BA=EF=BC=8C?= =?UTF-8?q?=E5=8E=BB=E6=8E=89=E6=97=B6=E9=95=BF=E4=B8=8E=E9=99=90=E9=AB=98?= =?UTF-8?q?=E6=BB=9A=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/renderer/src/components/Thinking.tsx | 57 +++++-------------- 1 file changed, 13 insertions(+), 44 deletions(-) diff --git a/apps/desktop/src/renderer/src/components/Thinking.tsx b/apps/desktop/src/renderer/src/components/Thinking.tsx index 40edbee..a5f0749 100644 --- a/apps/desktop/src/renderer/src/components/Thinking.tsx +++ b/apps/desktop/src/renderer/src/components/Thinking.tsx @@ -1,10 +1,10 @@ -import { useEffect, useRef, useState } from 'react' +import { useRef, useState } from 'react' import type { ReactNode } from 'react' /** 可展开的思考轨迹(ZCode 式实时预览)。 - * 流式中:展开区为限高滚动预览——新内容在尾部并自动吸底,用户上滚即取消 - * 吸底(滚回底部恢复),表头显示「正在思考 · 持续了 N 秒」;收起时表头 - * 改为「正在思考 · 最新一行」持续刷新。结束后收起为「思考过程 · 持续了 N 秒」, + * 流式收起时表头显示「正在思考 · 最新一行」持续刷新,不展示全部; + * 展开时完整展示全部思考(不截断),新内容在尾部、由会话级自动滚动跟随, + * 用户上滚即取消跟随(外层滚动已实现)。结束后收起为「思考过程」, * 点击表头可手动展开/收起。rows 由真实思考文本逐行喂入。 */ export function Thinking({ rows, @@ -20,44 +20,17 @@ export function Thinking({ const [manualExpanded, setManualExpanded] = useState(null) const expanded = manualExpanded ?? streaming - // 已思考时长:流式期间每秒递增;分段间歇(streaming 抖动)暂停但不清零 - const [secs, setSecs] = useState(0) - useEffect(() => { - if (!streaming) return - const t = setInterval(() => setSecs((s) => s + 1), 1000) - return () => clearInterval(t) - }, [streaming]) - - // 滚动吸底:新内容到达且当前贴着底部时跟随;用户上滚即取消,滚回底部恢复。 - // 收起时重置为吸底,重新展开直接落在最新内容。 - const scrollRef = useRef(null) - const pinnedRef = useRef(true) - const handleScroll = (): void => { - const el = scrollRef.current - if (!el) return - pinnedRef.current = el.scrollHeight - el.scrollTop - el.clientHeight < 24 - } - useEffect(() => { - if (!expanded) { - pinnedRef.current = true - return - } - const el = scrollRef.current - if (el && pinnedRef.current) el.scrollTop = el.scrollHeight - }, [rows, expanded]) - // 流式轨迹的行必须「随到随显」:fade-up 的 both+delay 会让新行在延迟期间 // 透明但占高,流式期间底部因此持续留出一大片空白。交错入场只保留给 // 非流式一次性渲染的静态轨迹(挂载时决定,之后不变更,避免整段重播动画)。 const streamedMountRef = useRef(streaming) - const statusWord = streaming ? activeLabel : expanded ? '思考' : doneLabel const latest = rows.length > 0 ? rows[rows.length - 1].primary : '' - const suffix = expanded ? (secs > 0 ? `持续了 ${secs} 秒` : '') : streaming ? latest : '' + const suffix = streaming && !expanded ? latest : '' return (
- {/* 表头:状态词 + 后缀(时长 / 最新一行)+ 旋转箭头 */} + {/* 表头:状态词 +(流式收起时)最新一行 + 旋转箭头 */} - {/* 展开轨迹:限高滚动预览(最新在尾部),左侧 hairline 随内容延伸 */} + {/* 展开轨迹:完整展示全部思考,左侧 hairline 随内容延伸 */}
-
-
- +
+ +
{rows.map((row, i) => (