diff --git a/frontend/src/components/messages/MessageComposer.tsx b/frontend/src/components/messages/MessageComposer.tsx index 8db46b18..274d11f3 100644 --- a/frontend/src/components/messages/MessageComposer.tsx +++ b/frontend/src/components/messages/MessageComposer.tsx @@ -1,8 +1,12 @@ "use client"; +import { useLayoutEffect, useState } from "react"; import type React from "react"; import { Paperclip, Send, Smile, X } from "lucide-react"; +const MIN_COMPOSER_HEIGHT = 42; +const MAX_COMPOSER_HEIGHT = 128; + type ReplyTarget = { id: number; author: string; @@ -58,6 +62,22 @@ export default function MessageComposer({ onCancelEdit, onCancelReply, }: MessageComposerProps) { + const [isExpanded, setIsExpanded] = useState(false); + const canSend = editingMessageId ? messageText.trim().length > 0 : messageText.trim().length > 0 || attachedFiles.length > 0; + + useLayoutEffect(() => { + const input = messageInputRef.current; + if (!input) return; + + input.style.height = "0px"; + const nextHeight = Math.min(input.scrollHeight, MAX_COMPOSER_HEIGHT); + const resolvedHeight = Math.max(nextHeight, MIN_COMPOSER_HEIGHT); + + input.style.height = `${resolvedHeight}px`; + input.style.overflowY = input.scrollHeight > MAX_COMPOSER_HEIGHT ? "auto" : "hidden"; + setIsExpanded(resolvedHeight > MIN_COMPOSER_HEIGHT + 2); + }, [messageText, messageInputRef]); + return ( <> {editingMessageId ? ( @@ -124,22 +144,34 @@ export default function MessageComposer({ className="hidden" onChange={onFilesChange} /> - + -