"use client";
import { useState } from "react";
import { SmilePlus, MessageSquare, Download, Loader2 } from "lucide-react";
import { cn } from "@/lib/utils";
import { UserAvatar } from "./UserAvatar";
import { AuthImage } from "./AuthImage";
import type { Message } from "@/hooks/useMessenger";
import { useAddReaction } from "@/hooks/useMessenger";
import { toast } from "sonner";
const QUICK_EMOJIS = ["\u{1F44D}", "\u{2764}\u{FE0F}", "\u{1F602}", "\u{1F44F}", "\u{1F64F}", "\u{1F525}"];
interface MessageItemProps {
message: Message;
isOwn: boolean;
showAvatar: boolean;
isLastInGroup: boolean;
}
export function MessageItem({ message, isOwn, showAvatar, isLastInGroup }: MessageItemProps) {
const [showActions, setShowActions] = useState(false);
const [showEmojiPicker, setShowEmojiPicker] = useState(false);
const [hovering, setHovering] = useState(false);
const [downloading, setDownloading] = useState(false);
const addReaction = useAddReaction();
if (message.isDeleted) {
return (
{showAvatar && !isOwn ? (
) : (
)}
삭제된 메시지입니다
);
}
const time = new Date(message.createdAt).toLocaleTimeString("ko-KR", {
hour: "2-digit",
minute: "2-digit",
});
// Time element — sibling of bubble column in the outer flex row
// isOwn: appears left of bubble (flex-row-reverse puts it visually left)
// !isOwn: appears right of bubble
const timeEl = (
{time}
);
return (
// DOM order: [avatar, bubble column, timeEl]
// isOwn flex-row-reverse → visual: [timeEl, bubble column, avatar]
// !isOwn normal → visual: [avatar, bubble column, timeEl]
{/* avatar */}
{!isOwn ? (
showAvatar ? (
) : (
)
) : (
)}
{/* bubble column — direct flex child: max-w-[65%] resolves against full chat panel width */}
{ setShowActions(true); setHovering(true); }}
onMouseLeave={() => { setShowActions(false); setShowEmojiPicker(false); setHovering(false); }}
>
{showAvatar && !isOwn && (
{message.senderName}
)}
{/* inline-block: sizes to content but constrained by parent max-w-[65%] */}
{message.type === "file" && message.fileMimeType?.startsWith("image/") && message.fileUrl ? (
) : (
{message.type === "file" && message.fileUrl ? (
) : (
{message.content}
)}
)}
{showActions && (
)}
{showEmojiPicker && (
{QUICK_EMOJIS.map((emoji) => (
))}
)}
{message.reactions.length > 0 && (
{message.reactions.map((r) => (
))}
)}
{/* time — direct flex child, sibling of bubble column */}
{timeEl}
);
}