import { useState, type ComponentProps } from "react"; import { X } from "lucide-react"; import { Button } from "@/shared/ui/button"; import { useAnswerViewPersistence, useAnswerViewState } from "../session-state/use-answer-view-state"; import type { AnswerViewStateScope } from "../session-state/answer-view-state-scope"; import { StreamingTokenResponse } from "../components/streaming-token-response"; import { AnswerUiView, type AnswerUiMapTarget } from "./answer-ui-view"; import type { AnswerUiPart } from "./contract"; export function AnswerPartsView({ parts, messageId, disabled, streaming, streamDone, persist = false, onLocate, onSubmit, }: { parts: AnswerUiPart[]; messageId: string; disabled: boolean; streaming: boolean; streamDone: boolean; persist?: boolean; onLocate?: (target: AnswerUiMapTarget) => Promise | void; onSubmit?: (text: string) => Promise | void; }) { const persistence = useAnswerViewPersistence(); return (
{parts.map((part, index) => part.type === "answer-ui" ? ( ) : ( ) )}
); } type PersistableProps = ComponentProps & { messageId: string; active: boolean; persistence: { scope: AnswerViewStateScope; sessionId: string } | null; }; function PersistableAnswerUiView({ persistence, messageId, active, ...props }: PersistableProps) { if (!persistence) return ; return ; } function SavedAnswerUiView({ persistence, messageId, active, ...props }: PersistableProps & { persistence: NonNullable }) { const saved = useAnswerViewState(persistence.scope, persistence.sessionId, messageId, props.block.block_id, props.block.spec, active); const [confirmReload, setConfirmReload] = useState(false); const label = { loading: "正在恢复交互状态", saving: "正在保存", saved: "已保存", unsaved: "未保存", conflict: "保存冲突" }[saved.status]; return
{active ?
{label} {saved.error ? {saved.error} : null} {saved.status === "unsaved" ? : null} {saved.status === "conflict" && !confirmReload ? <> : null} {confirmReload ?
重新加载将替换本块的本地筛选与表单草稿。
: null}
: null}
; }