import { useEffect, useMemo, useRef } from 'react';
function getMediaUrl(media) {
if (!media?.data || !media?.mimetype) return '';
return `data:${media.mimetype};base64,${media.data}`;
}
function parseMessageText(text) {
const rawText = String(text || '');
const match = rawText.match(/^\*(Atendente(?: virtual)?:\s*[^*]+)\*\s*\n+/i);
if (!match) {
return {
senderLabel: null,
body: rawText,
};
}
return {
senderLabel: match[1],
body: rawText.slice(match[0].length),
};
}
function formatMessageTime(timestamp) {
if (!timestamp) return '';
const numericTimestamp = Number(timestamp);
const date = new Date(numericTimestamp > 1000000000000 ? numericTimestamp : numericTimestamp * 1000);
return date.toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit' });
}
function MediaRenderer({ message, contactId, onLoadMedia, isAgent }) {
const mediaUrl = useMemo(() => getMediaUrl(message.media), [message.media]);
const mimetype = message.media?.mimetype || '';
const filename = message.media?.filename || 'arquivo';
useEffect(() => {
if (!message.hasMedia || message.media?.data || message.mediaLoading || message.mediaError) {
return;
}
onLoadMedia?.(contactId, message.id);
}, [contactId, message, onLoadMedia]);
if (!message.hasMedia && !message.media) return null;
if (message.mediaLoading || (!message.media?.data && !message.mediaError)) {
return (
Carregando midia...
);
}
if (message.mediaError) {
return (
Nao foi possivel carregar a midia.
);
}
if (mimetype.startsWith('image/')) {
return (
{
event.currentTarget.style.transform = 'scale(1.015)';
}}
onMouseLeave={(event) => {
event.currentTarget.style.transform = 'scale(1)';
}}
/>
);
}
if (mimetype.startsWith('video/')) {
return (
);
}
if (mimetype.startsWith('audio/') || mimetype.includes('ogg')) {
return ;
}
return (
📄
{filename}
);
}
function AttachmentPreview({ file, onRemove }) {
if (!file) return null;
const mediaUrl = getMediaUrl({ data: file.data, mimetype: file.type });
return (
{file.type?.startsWith('image/') ? (

) : (
📎
)}
{file.name}
{file.type || 'arquivo'}
);
}
function ContactActivity({ contact }) {
if (!contact) {
return null;
}
const status = contact.status || 'offline';
const color = status === 'away' ? '#e5a22a' : '#dc2626';
const label = contact.lastSeen || 'Sem atividade recente';
return (
{label}
);
}
export function ChatWindow({
contact,
messages,
selectedArea,
setSelectedArea,
draft,
setDraft,
attachedFile,
onAttachFile,
onRemoveAttachedFile,
onLoadMedia,
onSend,
onToggleTransfer,
onAssumeChat,
onReleaseChat,
canAssumeChat = false,
canReply = true,
assignmentLabel,
isReplying,
isMobile = false,
}) {
const messagesRef = useRef(null);
const safeContact = contact || {
id: '',
name: 'Nenhuma conversa ativa',
status: 'offline',
lastSeen: 'Aguardando fila do Omnino',
};
useEffect(() => {
const container = messagesRef.current;
if (!container) {
return;
}
container.scrollTo({
top: container.scrollHeight,
behavior: 'smooth',
});
}, [messages, isReplying]);
return (
{safeContact.name}
{canAssumeChat ? (
) : null}
{canReply ? (
) : null}
{messages.map((message) => {
const isAgent = message.sender === 'agent';
const isSystem = message.sender === 'system';
const parsedText = parseMessageText(message.text);
const messageTime = formatMessageTime(message.timestamp);
if (isSystem) {
return (
{message.text}
);
}
return (
{parsedText.senderLabel ? (
{parsedText.senderLabel}
) : null}
{parsedText.body ? (
{parsedText.body}
) : null}
{messageTime ? (
{messageTime}
) : null}
);
})}
{messages.length === 0 ? (
Nenhuma mensagem carregada.
) : null}
{isReplying ? (
Digitando...
) : null}
);
}