From 9c4753bc3f789c95c6ba257688c8bdd291d348cb Mon Sep 17 00:00:00 2001 From: Akash Santra Date: Wed, 19 Aug 2026 11:02:17 +0530 Subject: [PATCH] style: message input section --- frontend/src/components/MessageInput.jsx | 395 +++++++++-------------- 1 file changed, 156 insertions(+), 239 deletions(-) diff --git a/frontend/src/components/MessageInput.jsx b/frontend/src/components/MessageInput.jsx index 934c66f..c8cb900 100644 --- a/frontend/src/components/MessageInput.jsx +++ b/frontend/src/components/MessageInput.jsx @@ -10,14 +10,12 @@ import { Clapperboard, BarChart2, } from "lucide-react"; - import toast from "react-hot-toast"; import { useChatStore } from "../store/useChatStore"; import EmojiPicker from "emoji-picker-react"; import GifPicker from "./GifPicker"; import PollCreatorModal from "./PollCreatorModal"; - const MessageInput = () => { const [text, setText] = useState(""); const [imagePreview, setImagePreview] = useState(null); @@ -29,7 +27,6 @@ const MessageInput = () => { const [dragActive, setDragActive] = useState(false); const [showPollModal, setShowPollModal] = useState(false); - const emojiRef = useRef(null); const gifRef = useRef(null); const fileRef = useRef(null); @@ -52,8 +49,8 @@ const MessageInput = () => { smartReplies, } = useChatStore(); - const isAI = selectedChatType === "private" && selectedUser?.isAI; + const hasContent = Boolean(text.trim() || imagePreview || fileData || audioData); useEffect(() => { return () => { @@ -133,7 +130,7 @@ const MessageInput = () => { const reader = new FileReader(); reader.onload = () => setAudioData(reader.result); reader.readAsDataURL(blob); - stream.getTracks().forEach((track) => track.stop()); // Clean up hardware use + stream.getTracks().forEach((track) => track.stop()); }; mediaRecorder.start(); @@ -164,7 +161,7 @@ const MessageInput = () => { const handleSend = async (e) => { e.preventDefault(); - if (!text.trim() && !imagePreview && !fileData && !audioData) return; + if (!hasContent) return; stopTyping(); @@ -184,13 +181,10 @@ const MessageInput = () => { : await sendMessage(payload); } - // Reset all states setText(""); setImagePreview(null); setFileData(null); setAudioData(null); - - // useChatStore.setState({ smartReplies: [] }); }; const handleDragOver = (e) => { @@ -229,55 +223,57 @@ const MessageInput = () => { return (
+ {/* Drop Zone Overlay */} {dragActive && ( -
-

- Drop file to upload +

+

+ Drop file here to upload

)} + + {/* Replying Banner */} {replyingTo && ( -
-
- Replying to - {replyingTo.text || "Media message"} +
+
+ Replying to: + {replyingTo.text || "Media attachment"}
)} + {/* Media & Attachment Previews */} {(imagePreview || fileData || audioData) && ( -
+
{imagePreview && ( setImagePreview(null)}> -
- Preview -
+ Preview
)} {fileData && ( setFileData(null)}> -
+
- + {fileData.name}
@@ -286,51 +282,31 @@ const MessageInput = () => { {audioData && ( setAudioData(null)}> -
+
- Voice message + Voice memo attached
)}
)} + {/* Smart Replies */} {smartReplies?.length > 0 && !isAI && ( -
- {/* Glow Background Effect */} -
- - {/* Close Button */} - - - {/* Title */} -

- Suggested Replies -

- - {/* Replies */} -
+
+
+ + Suggested Replies + + +
+
{smartReplies.map((reply, index) => ( @@ -364,189 +324,146 @@ const MessageInput = () => {
)} -
-
-
- handleTyping(e.target.value)} - onBlur={stopTyping} - placeholder={isAI ? "Ask AI assistant…" : "Message"} - disabled={recording} - className=" - w-full min-w-0 - h-11 sm:h-12 - px-3 sm:px-4 - text-sm sm:text-base - rounded-full - bg-base-200/70 - placeholder:text-base-content/40 - focus:outline-none - focus:bg-base-100 - focus:ring-2 - focus:ring-primary/30 - transition-all - disabled:opacity-50 - disabled:cursor-not-allowed - " - /> - -{!isAI && ( -
- - - -
- - - {showEmojiPicker && ( -
+ {/* Main Bar */} + + {/* Unified Input Bar */} +
+ handleTyping(e.target.value)} + onBlur={stopTyping} + placeholder={isAI ? "Ask AI assistant…" : "Type a message…"} + disabled={recording} + className="flex-1 bg-transparent px-2.5 py-2 text-sm text-base-content placeholder:text-base-content/40 outline-none disabled:opacity-50" + /> + + {!isAI && ( +
+ + + + {/* Emoji Picker Button */} +
+ + + {showEmojiPicker && ( +
)} -
+
+ {/* Image Button */} + + + {/* GIF Picker Button */} +
- -
- - - {showGifPicker && ( -
- setShowGifPicker(false)} - /> -
- )} -
- - - {/* Poll button — group chats only */} - {selectedChatType === "group" && ( - + {showGifPicker && ( +
+ setShowGifPicker(false)} + /> +
)} -
- )} -
-
-
- {!isAI && ( -
- {!recording ? ( - - ) : ( + {/* Attachment Button */} + + + {/* Poll Button (Group chats only) */} + {selectedChatType === "group" && ( )}
)} +
+ {/* Audio Recording / Mic Button */} + {!isAI && ( -
+ )} + + {/* Send Button */} + - {/* Poll creator modal — rendered outside form to avoid nesting issues */} + {/* Poll Creator Modal */} setShowPollModal(false)} @@ -561,12 +478,12 @@ const Preview = ({ children, onRemove }) => ( {children}
); -export default MessageInput; - +export default MessageInput; \ No newline at end of file