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>
This commit is contained in:
dekun
2026-06-10 22:56:22 +08:00
parent 38bbc7145a
commit 39181f21ad
7 changed files with 118 additions and 39 deletions
+1 -1
View File
@@ -163,7 +163,7 @@ export default function BaziForm() {
)}
{showAi && (
<div className="mx-auto h-96 w-full max-w-lg flex-1">
<div className="mx-auto w-full max-w-lg pt-2">
<ResultAI
completion={completion}
isLoading={isLoading}
+1 -1
View File
@@ -299,7 +299,7 @@ export default function CombinedForm() {
)}
{showAi && (
<div className="mx-auto h-96 w-full max-w-lg flex-1">
<div className="mx-auto w-full max-w-lg pt-2">
<ResultAI
completion={completion}
isLoading={isLoading}
+1 -1
View File
@@ -229,7 +229,7 @@ export default function LiuyaoForm() {
</div>
{showAi && (
<div className="mx-auto h-96 w-full max-w-lg flex-1">
<div className="mx-auto w-full max-w-lg pt-2">
<ResultAI
completion={completion}
isLoading={isLoading}
+20 -32
View File
@@ -25,60 +25,48 @@ function ResultAI({
if (!autoScroll) {
return;
}
scrollTo();
});
function scrollTo() {
requestAnimationFrame(() => {
if (
!scrollRef.current ||
scrollRef.current.scrollHeight ===
scrollRef.current.clientHeight + scrollRef.current.scrollTop
) {
return;
}
scrollRef.current.scrollTo(0, scrollRef.current.scrollHeight);
});
}
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) {
return;
if (hitBottom !== autoScroll) {
setAutoScroll(hitBottom);
}
setAutoScroll(hitBottom);
}
return (
<div className="h-0 w-full flex-1 sm:max-w-md md:max-w-2xl">
<div className="flex w-full flex-col gap-2">
{isLoading && (
<div className="flex h-0">
<span className="flex-1" />
<div className="relative -top-4 flex w-fit items-center pr-1 text-muted-foreground sm:left-2 sm:pr-3">
<RotateCw size={16} className="animate-spin" />
<span className="ml-1 text-sm">AI ...</span>
</div>
<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="max-h-full overflow-auto rounded-md border p-3 shadow dark:border-0 dark:bg-secondary/90 dark:shadow-none sm:p-5"
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-destructive">
_ಠ
<br />
{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>
) : (
<Markdown className="prose dark:prose-invert">{completion}</Markdown>
<p className="text-sm text-muted-foreground"></p>
)}
{!isLoading && (
<Button onClick={onCompletion} size="sm" className="mt-2">
<Button onClick={onCompletion} size="sm" className="mt-3">
<RotateCw size={18} className="mr-1" />
</Button>