import { IconArrowUp, IconPhotoPlus, IconX } from "@tabler/icons-react" import type { KeyboardEvent } from "react" import { useTranslation } from "react-i18next" import TextareaAutosize from "react-textarea-autosize" import { Button } from "@/components/ui/button" import { cn } from "@/lib/utils" import type { ChatAttachment } from "@/store/chat" export type ChatInputDisabledReason = | "gatewayUnknown" | "gatewayStarting" | "gatewayRestarting" | "gatewayStopping" | "gatewayStopped" | "gatewayError" | "websocketConnecting" | "websocketDisconnected" | "websocketError" | "noDefaultModel" interface ChatComposerProps { input: string attachments: ChatAttachment[] onInputChange: (value: string) => void onAddImages: () => void onRemoveAttachment: (index: number) => void onSend: () => void inputDisabledReason: ChatInputDisabledReason | null canSend: boolean } export function ChatComposer({ input, attachments, onInputChange, onAddImages, onRemoveAttachment, onSend, inputDisabledReason, canSend, }: ChatComposerProps) { const { t } = useTranslation() const canInput = inputDisabledReason === null const disabledMessage = inputDisabledReason === null ? null : t(`chat.disabledPlaceholder.${inputDisabledReason}`) const placeholder = disabledMessage ?? t("chat.placeholder") const handleKeyDown = (e: KeyboardEvent) => { if (e.nativeEvent.isComposing) return if (e.key === "Enter" && !e.shiftKey) { e.preventDefault() onSend() } } return (
{attachments.length > 0 && (
{attachments.map((attachment, index) => (
{attachment.filename
))}
)} onInputChange(e.target.value)} onKeyDown={handleKeyDown} placeholder={placeholder} disabled={!canInput} title={disabledMessage || undefined} className={cn( "placeholder:text-muted-foreground/50 max-h-[200px] min-h-[60px] resize-none border-0 bg-transparent px-2 py-1 text-[15px] shadow-none transition-colors focus-visible:ring-0 focus-visible:outline-none dark:bg-transparent", !canInput && "cursor-not-allowed", )} minRows={1} maxRows={8} /> {!canInput && disabledMessage && (
{disabledMessage}
)}
{canInput ? ( ) : null}
) }