diff --git a/frontend/web/src/components/ChatInput.tsx b/frontend/web/src/components/ChatInput.tsx index 62ebefe..95250e8 100644 --- a/frontend/web/src/components/ChatInput.tsx +++ b/frontend/web/src/components/ChatInput.tsx @@ -3,7 +3,7 @@ import { Button } from "./primitives"; import { Icon } from "./Icon"; export interface ChatInputProps { - onSend: (text: string) => void; + onSend: (text: string, image?: string) => void; sending: boolean; onVoice: () => void; placeholder?: string; @@ -16,7 +16,9 @@ export function ChatInput({ placeholder = "给昔涟发消息…", }: ChatInputProps): React.ReactNode { const [value, setValue] = useState(""); + const [pendingImage, setPendingImage] = useState(undefined); const taRef = useRef(null); + const fileRef = useRef(null); // auto-grow the textarea up to a max height useEffect(() => { @@ -26,45 +28,92 @@ export function ChatInput({ el.style.height = Math.min(el.scrollHeight, 140) + "px"; }, [value]); + const onPickFile = (e: React.ChangeEvent) => { + const f = e.target.files?.[0]; + if (!f) return; + const reader = new FileReader(); + reader.onload = () => { + if (typeof reader.result === "string") setPendingImage(reader.result); + }; + reader.readAsDataURL(f); + e.target.value = ""; + }; + + const canSend = value.trim().length > 0 || Boolean(pendingImage); + const submit = () => { - const t = value.trim(); - if (!t || sending) return; - onSend(t); + if (sending || !canSend) return; + onSend(value.trim(), pendingImage); setValue(""); + setPendingImage(undefined); }; return (
-
-