import { useEffect, useRef } from 'react'; import { Brain, PenLine } from 'lucide-react'; import type { StreamingDraftSection } from '../../types/ai-writing'; interface DraftGeneratingViewProps { sections: StreamingDraftSection[]; } /** 思考过程框:纯只读展示,跟随内容自动滚到底(仅操作 DOM,不触发 setState) */ function ThinkingBox({ text, done }: { text: string; done: boolean }) { const preRef = useRef(null); useEffect(() => { if (preRef.current) preRef.current.scrollTop = preRef.current.scrollHeight; }, [text]); return (
思考过程
        {text}
        {!done && (
          
        )}
      
); } /** 「内容生成中」骨架屏:流光扫过的占位行 + 写字笔抖动 + 跳动圆点,提示正文正在右侧实时生成 */ const SKELETON_WIDTHS = ['92%', '100%', '85%', '96%', '70%']; function GeneratingSkeleton() { return (
{/* 顶部一道缓慢流过的高光,强化"正在工作"的呼吸感 */}
内容生成中 正文已在右侧实时显示
{SKELETON_WIDTHS.map((w, i) => (
))}
); } /** * 作家写作 / 按意见修改阶段,左侧的轻量「生成中」视图。 * * 刻意不再逐章节渲染流式正文(那套 DraftStreamingView 含逐 chunk 的平滑 * scrollIntoView 等重型操作):正文已在右侧实时显示,左侧只需告知"正在生成", * 若模型有思考过程则一并展示。这样左侧每个 chunk 的渲染开销极小,避免更新风暴。 */ export function DraftGeneratingView({ sections }: DraftGeneratingViewProps) { // 按章节顺序拼接非空思考内容;是否仍在思考以"存在未完成章节"近似 const ordered = [...sections].sort((a, b) => a.sectionIndex - b.sectionIndex); const thinking = ordered.map((s) => s.thinkingText).filter(Boolean).join('\n\n'); const thinkingDone = sections.length > 0 && sections.every((s) => s.isDone); return (
{thinking && }
); }