Add thinking placeholder message (#496)
This commit is contained in:
parent
0001c24d09
commit
b5c165714b
4 changed files with 67 additions and 13 deletions
|
|
@ -3,17 +3,10 @@
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { type User } from 'next-auth';
|
import { type User } from 'next-auth';
|
||||||
|
|
||||||
import { PlusIcon, VercelIcon } from '@/components/custom/icons';
|
import { PlusIcon } from '@/components/custom/icons';
|
||||||
import { SidebarHistory } from '@/components/custom/sidebar-history';
|
import { SidebarHistory } from '@/components/custom/sidebar-history';
|
||||||
import { SidebarUserNav } from '@/components/custom/sidebar-user-nav';
|
import { SidebarUserNav } from '@/components/custom/sidebar-user-nav';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import {
|
|
||||||
Card,
|
|
||||||
CardDescription,
|
|
||||||
CardFooter,
|
|
||||||
CardHeader,
|
|
||||||
CardTitle,
|
|
||||||
} from '@/components/ui/card';
|
|
||||||
import {
|
import {
|
||||||
Sidebar,
|
Sidebar,
|
||||||
SidebarContent,
|
SidebarContent,
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import useSWR, { useSWRConfig } from 'swr';
|
||||||
import { useWindowSize } from 'usehooks-ts';
|
import { useWindowSize } from 'usehooks-ts';
|
||||||
|
|
||||||
import { ChatHeader } from '@/components/custom/chat-header';
|
import { ChatHeader } from '@/components/custom/chat-header';
|
||||||
import { PreviewMessage } from '@/components/custom/message';
|
import { PreviewMessage, ThinkingMessage } from '@/components/custom/message';
|
||||||
import { useScrollToBottom } from '@/components/custom/use-scroll-to-bottom';
|
import { useScrollToBottom } from '@/components/custom/use-scroll-to-bottom';
|
||||||
import { Vote } from '@/db/schema';
|
import { Vote } from '@/db/schema';
|
||||||
import { fetcher } from '@/lib/utils';
|
import { fetcher } from '@/lib/utils';
|
||||||
|
|
@ -100,6 +100,12 @@ export function Chat({
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
|
{isLoading &&
|
||||||
|
messages.length > 0 &&
|
||||||
|
messages[messages.length - 1].role === 'user' && (
|
||||||
|
<ThinkingMessage />
|
||||||
|
)}
|
||||||
|
|
||||||
<div
|
<div
|
||||||
ref={messagesEndRef}
|
ref={messagesEndRef}
|
||||||
className="shrink-0 min-w-[24px] min-h-[24px]"
|
className="shrink-0 min-w-[24px] min-h-[24px]"
|
||||||
|
|
|
||||||
|
|
@ -798,7 +798,7 @@ export const ThumbDownIcon = ({ size = 16 }: { size?: number }) => (
|
||||||
);
|
);
|
||||||
|
|
||||||
export const ChevronDownIcon = ({ size = 16 }: { size?: number }) => (
|
export const ChevronDownIcon = ({ size = 16 }: { size?: number }) => (
|
||||||
<svg
|
<svg
|
||||||
height={size}
|
height={size}
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
|
|
@ -813,3 +813,26 @@ export const ChevronDownIcon = ({ size = 16 }: { size?: number }) => (
|
||||||
></path>
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const SparklesIcon = ({ size = 16 }: { size?: number }) => (
|
||||||
|
<svg
|
||||||
|
height={size}
|
||||||
|
strokeLinejoin="round"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
width={size}
|
||||||
|
style={{ color: 'currentcolor' }}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M2.5 0.5V0H3.5V0.5C3.5 1.60457 4.39543 2.5 5.5 2.5H6V3V3.5H5.5C4.39543 3.5 3.5 4.39543 3.5 5.5V6H3H2.5V5.5C2.5 4.39543 1.60457 3.5 0.5 3.5H0V3V2.5H0.5C1.60457 2.5 2.5 1.60457 2.5 0.5Z"
|
||||||
|
fill="currentColor"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
d="M14.5 4.5V5H13.5V4.5C13.5 3.94772 13.0523 3.5 12.5 3.5H12V3V2.5H12.5C13.0523 2.5 13.5 2.05228 13.5 1.5V1H14H14.5V1.5C14.5 2.05228 14.9477 2.5 15.5 2.5H16V3V3.5H15.5C14.9477 3.5 14.5 3.94772 14.5 4.5Z"
|
||||||
|
fill="currentColor"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
d="M8.40706 4.92939L8.5 4H9.5L9.59294 4.92939C9.82973 7.29734 11.7027 9.17027 14.0706 9.40706L15 9.5V10.5L14.0706 10.5929C11.7027 10.8297 9.82973 12.7027 9.59294 15.0706L9.5 16H8.5L8.40706 15.0706C8.17027 12.7027 6.29734 10.8297 3.92939 10.5929L3 10.5V9.5L3.92939 9.40706C6.29734 9.17027 8.17027 7.29734 8.40706 4.92939Z"
|
||||||
|
fill="currentColor"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,13 @@
|
||||||
import { Message } from 'ai';
|
import { Message } from 'ai';
|
||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
import { motion } from 'framer-motion';
|
import { motion } from 'framer-motion';
|
||||||
import { Sparkles } from 'lucide-react';
|
|
||||||
import { Dispatch, SetStateAction } from 'react';
|
import { Dispatch, SetStateAction } from 'react';
|
||||||
|
|
||||||
import { Vote } from '@/db/schema';
|
import { Vote } from '@/db/schema';
|
||||||
|
|
||||||
import { UICanvas } from './canvas';
|
import { UICanvas } from './canvas';
|
||||||
import { DocumentToolCall, DocumentToolResult } from './document';
|
import { DocumentToolCall, DocumentToolResult } from './document';
|
||||||
|
import { SparklesIcon } from './icons';
|
||||||
import { Markdown } from './markdown';
|
import { Markdown } from './markdown';
|
||||||
import { MessageActions } from './message-actions';
|
import { MessageActions } from './message-actions';
|
||||||
import { PreviewAttachment } from './preview-attachment';
|
import { PreviewAttachment } from './preview-attachment';
|
||||||
|
|
@ -49,7 +49,7 @@ export const PreviewMessage = ({
|
||||||
>
|
>
|
||||||
{message.role === 'assistant' && (
|
{message.role === 'assistant' && (
|
||||||
<div className="size-8 flex items-center rounded-full justify-center ring-1 shrink-0 ring-border">
|
<div className="size-8 flex items-center rounded-full justify-center ring-1 shrink-0 ring-border">
|
||||||
<Sparkles className="size-4" />
|
<SparklesIcon size={14} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
@ -148,3 +148,35 @@ export const PreviewMessage = ({
|
||||||
</motion.div>
|
</motion.div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const ThinkingMessage = () => {
|
||||||
|
const role = 'assistant';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<motion.div
|
||||||
|
className="w-full mx-auto max-w-3xl px-4 group/message "
|
||||||
|
initial={{ y: 5, opacity: 0 }}
|
||||||
|
animate={{ y: 0, opacity: 1, transition: { delay: 1 } }}
|
||||||
|
data-role={role}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={cx(
|
||||||
|
'flex gap-4 group-data-[role=user]/message:px-3 w-full group-data-[role=user]/message:w-fit group-data-[role=user]/message:ml-auto group-data-[role=user]/message:max-w-2xl group-data-[role=user]/message:py-2 rounded-xl',
|
||||||
|
{
|
||||||
|
'group-data-[role=user]/message:bg-muted': true,
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div className="size-8 flex items-center rounded-full justify-center ring-1 shrink-0 ring-border">
|
||||||
|
<SparklesIcon size={14} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col gap-2 w-full">
|
||||||
|
<div className="flex flex-col gap-4 text-muted-foreground">
|
||||||
|
Thinking...
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue