fix: remove zustand and use input and setInput

This commit is contained in:
shadcn 2023-06-13 22:16:54 +04:00
parent 6f69b878d5
commit f476c903ef
8 changed files with 83 additions and 95 deletions

View file

@ -4,25 +4,24 @@ import { type Message } from 'ai-connector'
import { Separator } from '@/components/ui/separator'
import { ChatMessage } from '@/components/chat-message'
import { EmptyScreen } from '@/components/empty-screen'
export interface ChatList {
messages: Message[]
}
export function ChatList({ messages }: ChatList) {
if (!messages.length) {
return null
}
return (
<div className="relative mx-auto max-w-2xl px-4">
{messages.length > 0 ? (
messages.map((message, index) => (
<div key={index}>
<ChatMessage message={message} />
{index < messages.length - 1 && <Separator className="my-8" />}
</div>
))
) : (
<EmptyScreen />
)}
{messages.map((message, index) => (
<div key={index}>
<ChatMessage message={message} />
{index < messages.length - 1 && <Separator className="my-8" />}
</div>
))}
</div>
)
}

View file

@ -1,4 +1,4 @@
import { UseChatHelpers } from 'ai-connector'
import { type UseChatHelpers } from 'ai-connector'
import { Button } from '@/components/ui/button'
import { ExternalLink } from '@/components/external-link'
@ -9,7 +9,13 @@ import { IconRefresh, IconStop } from '@/components/ui/icons'
export interface ChatPanelProps
extends Pick<
UseChatHelpers,
'append' | 'isLoading' | 'reload' | 'messages' | 'stop'
| 'append'
| 'isLoading'
| 'reload'
| 'messages'
| 'stop'
| 'input'
| 'setInput'
> {
id?: string
}
@ -19,6 +25,8 @@ export function ChatPanel({
stop,
append,
reload,
input,
setInput,
messages
}: ChatPanelProps) {
return (
@ -56,6 +64,8 @@ export function ChatPanel({
role: 'user'
})
}}
input={input}
setInput={setInput}
isLoading={isLoading}
/>
<p className="hidden px-2 text-center text-xs leading-normal text-muted-foreground sm:block">

View file

@ -2,24 +2,32 @@
import { useChat, type Message } from 'ai-connector'
import { cn } from '@/lib/utils'
import { ChatList } from '@/components/chat-list'
import { ChatPanel } from '@/components/chat-panel'
import { EmptyScreen } from '@/components/empty-screen'
export interface ChatProps {
// create?: (input: string) => Chat | undefined;
export interface ChatProps extends React.ComponentProps<'div'> {
initialMessages?: Message[]
id?: string
}
export function Chat({ id, initialMessages }: ChatProps) {
const { messages, append, reload, stop, isLoading } = useChat({
initialMessages,
id
})
export function Chat({ id, initialMessages, className }: ChatProps) {
const { messages, append, reload, stop, isLoading, input, setInput } =
useChat({
initialMessages,
id
})
return (
<div className="pb-[200px] pt-4 md:pt-10">
<ChatList messages={messages} />
<>
<div className={cn('pb-[200px] pt-4 md:pt-10', className)}>
{messages.length ? (
<ChatList messages={messages} />
) : (
<EmptyScreen setInput={setInput} />
)}
</div>
<ChatPanel
id={id}
isLoading={isLoading}
@ -27,7 +35,9 @@ export function Chat({ id, initialMessages }: ChatProps) {
append={append}
reload={reload}
messages={messages}
input={input}
setInput={setInput}
/>
</div>
</>
)
}

View file

@ -1,8 +1,8 @@
import { useChatStore } from '@/lib/hooks/use-chat-store'
import { cn } from '@/lib/utils'
import { Button } from '@/components/ui/button'
import { ExternalLink } from '@/components/external-link'
import { IconArrowRight } from '@/components/ui/icons'
import { UseChatHelpers } from 'ai-connector'
const exampleMessages = [
{
@ -19,37 +19,37 @@ const exampleMessages = [
}
]
export function EmptyScreen({ className }: React.ComponentProps<'div'>) {
const { setDefaultMessage } = useChatStore()
export function EmptyScreen({ setInput }: Pick<UseChatHelpers, 'setInput'>) {
return (
<div className={cn('rounded-lg border bg-background p-8', className)}>
<h1 className="mb-2 text-lg font-semibold">
Welcome to Next.js Chatbot!
</h1>
<p className="mb-2 leading-normal text-muted-foreground">
This is an open source AI chatbot app built with{' '}
<ExternalLink href="https://nextjs.org">Next.js</ExternalLink> and{' '}
<ExternalLink href="https://vercel.com/storage/kv">
Vercel KV
</ExternalLink>
.
</p>
<p className="leading-normal text-muted-foreground">
You can start a conversation here or try the following examples:
</p>
<div className="mt-4 flex flex-col items-start space-y-2">
{exampleMessages.map((message, index) => (
<Button
key={index}
variant="link"
className="h-auto p-0 text-base"
onClick={() => setDefaultMessage(message.message)}
>
<IconArrowRight className="mr-2 text-muted-foreground" />
{message.heading}
</Button>
))}
<div className="mx-auto max-w-2xl px-4">
<div className="rounded-lg border bg-background p-8">
<h1 className="mb-2 text-lg font-semibold">
Welcome to Next.js Chatbot!
</h1>
<p className="mb-2 leading-normal text-muted-foreground">
This is an open source AI chatbot app built with{' '}
<ExternalLink href="https://nextjs.org">Next.js</ExternalLink> and{' '}
<ExternalLink href="https://vercel.com/storage/kv">
Vercel KV
</ExternalLink>
.
</p>
<p className="leading-normal text-muted-foreground">
You can start a conversation here or try the following examples:
</p>
<div className="mt-4 flex flex-col items-start space-y-2">
{exampleMessages.map((message, index) => (
<Button
key={index}
variant="link"
className="h-auto p-0 text-base"
onClick={() => setInput(message.message)}
>
<IconArrowRight className="mr-2 text-muted-foreground" />
{message.heading}
</Button>
))}
</div>
</div>
</div>
)

View file

@ -2,7 +2,6 @@ import * as React from 'react'
import Link from 'next/link'
import Textarea from 'react-textarea-autosize'
import { useChatStore } from '@/lib/hooks/use-chat-store'
import { useEnterSubmit } from '@/lib/hooks/use-enter-submit'
import { cn } from '@/lib/utils'
import { Button, buttonVariants } from '@/components/ui/button'
@ -13,15 +12,20 @@ import {
TooltipTrigger
} from '@/components/ui/tooltip'
import { IconArrowElbow, IconPlus } from '@/components/ui/icons'
import { UseChatHelpers } from 'ai-connector'
export interface PromptProps {
export interface PromptProps
extends Pick<UseChatHelpers, 'input' | 'setInput'> {
onSubmit: (value: string) => void
isLoading: boolean
}
export function PromptForm({ onSubmit, isLoading }: PromptProps) {
const { defaultMessage } = useChatStore()
const [input, setInput] = React.useState(defaultMessage)
export function PromptForm({
onSubmit,
input,
setInput,
isLoading
}: PromptProps) {
const { formRef, onKeyDown } = useEnterSubmit()
const inputRef = React.useRef<HTMLTextAreaElement>(null)
@ -31,10 +35,6 @@ export function PromptForm({ onSubmit, isLoading }: PromptProps) {
}
}, [])
React.useEffect(() => {
setInput(defaultMessage)
}, [defaultMessage])
return (
<form
onSubmit={async e => {

View file

@ -1,11 +0,0 @@
import { create } from 'zustand'
interface UseChatStore {
defaultMessage: string
setDefaultMessage: (message: string) => void
}
export const useChatStore = create<UseChatStore>()(set => ({
defaultMessage: '',
setDefaultMessage: message => set({ defaultMessage: message })
}))

View file

@ -39,8 +39,7 @@
"react-syntax-highlighter": "^15.5.0",
"react-textarea-autosize": "^8.4.1",
"remark-gfm": "^3.0.1",
"remark-math": "^5.1.1",
"zustand": "^4.3.8"
"remark-math": "^5.1.1"
},
"devDependencies": {
"@tailwindcss/typography": "^0.5.9",

19
pnpm-lock.yaml generated
View file

@ -86,9 +86,6 @@ dependencies:
remark-math:
specifier: ^5.1.1
version: 5.1.1
zustand:
specifier: ^4.3.8
version: 4.3.8(react@18.2.0)
devDependencies:
'@tailwindcss/typography':
@ -5070,22 +5067,6 @@ packages:
/zod@3.21.4:
resolution: {integrity: sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==}
/zustand@4.3.8(react@18.2.0):
resolution: {integrity: sha512-4h28KCkHg5ii/wcFFJ5Fp+k1J3gJoasaIbppdgZFO4BPJnsNxL0mQXBSFgOgAdCdBj35aDTPvdAJReTMntFPGg==}
engines: {node: '>=12.7.0'}
peerDependencies:
immer: '>=9.0'
react: '>=16.8'
peerDependenciesMeta:
immer:
optional: true
react:
optional: true
dependencies:
react: 18.2.0
use-sync-external-store: 1.2.0(react@18.2.0)
dev: false
/zwitch@2.0.4:
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
dev: false