"use client"; import { useRef, useState } from "react"; import { useChatDispatch } from "@/stores/chat/chat-context"; import { useKeyboardHeight } from "@/hooks"; import { Logger } from "@/utils"; import { ChatInputTextField } from "./chat-input-text-field"; import { ChatSendButton } from "./chat-send-button"; import styles from "./chat-input-bar.module.css"; const log = new Logger("AppChatComponentsChatInputBar"); const POINTER_SEND_CLICK_DEDUPE_MS = 500; export interface ChatInputBarProps { disabled?: boolean; } export function ChatInputBar({ disabled = false }: ChatInputBarProps) { const dispatch = useChatDispatch(); const [input, setInput] = useState(""); const [isFocused, setIsFocused] = useState(false); const textareaRef = useRef(null); const lastPointerSendAtRef = useRef(0); const hasContent = input.trim().length > 0; useKeyboardHeight({ targetRef: textareaRef, active: isFocused, }); const handleInputChange = (value: string) => { setInput(value); }; const handleSend = (source: "click" | "keyboard" | "pointerdown") => { if (source === "click") { const elapsed = Date.now() - lastPointerSendAtRef.current; if (elapsed >= 0 && elapsed < POINTER_SEND_CLICK_DEDUPE_MS) { log.debug("[chat-input-bar] suppress duplicate click", { elapsed, contentLength: input.length, hasContent, disabled, isFocused, }); return; } } if (disabled || !hasContent) return; log.debug("[chat-input-bar] handleSend", { source, contentLength: input.length, contentPreview: input.slice(0, 50), hasContent, disabled, isFocused, }); dispatch({ type: "ChatSendMessage", content: input }); setInput(""); textareaRef.current?.focus(); }; const handlePointerDownSend = () => { lastPointerSendAtRef.current = Date.now(); handleSend("pointerdown"); }; return (
handleSend("keyboard")} onFocusChange={setIsFocused} disabled={disabled} /> handleSend("click")} onPointerDownSend={handlePointerDownSend} />
); }