e30e75b5d4
Changesets / Create Version PR (push) Has been cancelled
Deploy Shadcn Registry / Deploy Production (push) Has been cancelled
Template Metrics / LOC + Bundle Size (push) Has been cancelled
Code Quality / Oxlint + Oxfmt (push) Has been cancelled
Code Quality / Template Sync (push) Has been cancelled
Code Quality / Build Changed Packages (push) Has been cancelled
Code Quality / Test Changed Packages (push) Has been cancelled
Deploy Expo Example / Deploy Production (push) Has been cancelled
Deploy Ink Example / Deploy Production (push) Has been cancelled
Python Tests / pytest (assistant-stream, 3.10) (push) Has been cancelled
Python Tests / pytest (assistant-stream, 3.12) (push) Has been cancelled
Python Tests / pytest (assistant-ui-sync-server-api, 3.10) (push) Has been cancelled
Python Tests / pytest (assistant-ui-sync-server-api, 3.12) (push) Has been cancelled
52 lines
1.5 KiB
TypeScript
52 lines
1.5 KiB
TypeScript
"use client";
|
|
|
|
import type { UIMessage } from "ai";
|
|
import { Message } from "./Message";
|
|
|
|
type ThreadProps = {
|
|
messages: UIMessage[];
|
|
isLoading: boolean;
|
|
children?: React.ReactNode;
|
|
};
|
|
|
|
function ThreadWelcome() {
|
|
return (
|
|
<div className="flex flex-1 flex-col items-center justify-center text-center">
|
|
<h2 className="text-lg font-semibold">How can I help you today?</h2>
|
|
<p className="text-muted-foreground mt-1 text-sm">
|
|
Send a message to start a conversation.
|
|
</p>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function LoadingIndicator() {
|
|
return (
|
|
<div className="flex items-center gap-1.5 py-2">
|
|
<span className="bg-muted-foreground/60 size-1.5 animate-bounce rounded-full [animation-delay:-0.3s]" />
|
|
<span className="bg-muted-foreground/60 size-1.5 animate-bounce rounded-full [animation-delay:-0.15s]" />
|
|
<span className="bg-muted-foreground/60 size-1.5 animate-bounce rounded-full" />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function Thread({ messages, isLoading, children }: ThreadProps) {
|
|
return (
|
|
<div className="flex h-full flex-col">
|
|
<div className="flex flex-1 flex-col overflow-y-auto px-4 py-6">
|
|
{messages.length === 0 ? (
|
|
<ThreadWelcome />
|
|
) : (
|
|
<div className="mx-auto w-full max-w-3xl space-y-4">
|
|
{messages.map((msg) => (
|
|
<Message key={msg.id} message={msg} />
|
|
))}
|
|
{isLoading && <LoadingIndicator />}
|
|
</div>
|
|
)}
|
|
</div>
|
|
<div className="mx-auto w-full max-w-3xl">{children}</div>
|
|
</div>
|
|
);
|
|
}
|