Files
zhimingge/components/result-ai.tsx
T
dekun 39181f21ad Fix AI result panel visibility and nginx streaming headers.
ResultAI had h-0 collapsing output; add X-Accel-Buffering no, clearer fetch errors, and NGINX.md for gate proxy setup.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-10 22:56:22 +08:00

80 lines
2.3 KiB
TypeScript

import React, { useEffect, useRef, useState } from "react";
import { Button } from "@/components/ui/button";
import { RotateCw } from "lucide-react";
import Markdown from "react-markdown";
function ResultAI({
completion,
isLoading,
onCompletion,
error,
}: {
completion: string;
isLoading: boolean;
onCompletion: () => void;
error: string;
}) {
const scrollRef = useRef<HTMLDivElement>(null);
const [autoScroll, setAutoScroll] = useState(false);
useEffect(() => {
setAutoScroll(isLoading);
}, [isLoading]);
useEffect(() => {
if (!autoScroll) {
return;
}
scrollRef.current?.scrollTo(0, scrollRef.current.scrollHeight);
}, [completion, autoScroll]);
function onScroll(e: HTMLElement) {
if (!isLoading) {
return;
}
const hitBottom = e.scrollTop + e.clientHeight >= e.scrollHeight - 15;
if (hitBottom !== autoScroll) {
setAutoScroll(hitBottom);
}
}
return (
<div className="flex w-full flex-col gap-2">
{isLoading && (
<div className="flex items-center text-sm text-muted-foreground">
<RotateCw size={16} className="animate-spin" />
<span className="ml-1">AI ...</span>
</div>
)}
<div
ref={scrollRef}
onScroll={(e) => onScroll(e.currentTarget)}
className="min-h-[240px] max-h-[420px] overflow-y-auto rounded-md border bg-background p-3 shadow sm:p-5 dark:border-0 dark:bg-secondary/90 dark:shadow-none"
>
{error ? (
<div className="text-sm text-destructive">
<p className="font-medium"></p>
<p className="mt-1 whitespace-pre-wrap">{error}</p>
</div>
) : completion ? (
<Markdown className="prose max-w-none dark:prose-invert">
{completion}
</Markdown>
) : isLoading ? (
<p className="text-sm text-muted-foreground"> AI ...</p>
) : (
<p className="text-sm text-muted-foreground"></p>
)}
{!isLoading && (
<Button onClick={onCompletion} size="sm" className="mt-3">
<RotateCw size={18} className="mr-1" />
</Button>
)}
</div>
</div>
);
}
export default ResultAI;