Update chat layout to match web version

- Client messages on left with white background and border
- Agent messages on right with black background
- Added circular avatars (User icon for client, Headphones for agent)
- Improved spacing and visual consistency

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
esdrasrenan 2025-12-07 13:24:40 -03:00
parent fd0e29514a
commit 7e270bcd3b

View file

@ -4,7 +4,7 @@ import { listen } from "@tauri-apps/api/event"
import { Store } from "@tauri-apps/plugin-store"
import { appLocalDataDir, join } from "@tauri-apps/api/path"
import { open } from "@tauri-apps/plugin-dialog"
import { Send, X, Minus, Loader2, Headphones, Paperclip, FileText, Image as ImageIcon, File } from "lucide-react"
import { Send, X, Minus, Loader2, Headphones, Paperclip, FileText, Image as ImageIcon, File, User } from "lucide-react"
import type { ChatMessage, ChatMessagesResponse, SendMessageResponse } from "./types"
const STORE_FILENAME = "machine-agent.json"
@ -381,58 +381,71 @@ export function ChatWidget({ ticketId }: ChatWidgetProps) {
</p>
</div>
) : (
<div className="space-y-3">
{messages.map((msg) => (
<div
key={msg.id}
className={`flex ${msg.isFromMachine ? "justify-end" : "justify-start"}`}
>
<div className="space-y-4">
{messages.map((msg) => {
// No desktop: isFromMachine=true significa mensagem do cliente (maquina)
// Layout igual à web: cliente à esquerda, agente à direita
const isAgent = !msg.isFromMachine
return (
<div
className={`max-w-[80%] rounded-2xl px-4 py-2 ${
msg.isFromMachine
? "bg-black text-white"
: "bg-slate-100 text-slate-900"
}`}
key={msg.id}
className={`flex gap-2 ${isAgent ? "flex-row-reverse" : "flex-row"}`}
>
{!msg.isFromMachine && (
<p className="mb-1 text-xs font-medium text-slate-500">
{msg.authorName}
</p>
)}
<p className="whitespace-pre-wrap text-sm">{msg.body}</p>
{/* Anexos */}
{msg.attachments && msg.attachments.length > 0 && (
<div className="mt-2 space-y-1">
{msg.attachments.map((att) => (
<div
key={att.storageId}
className={`flex items-center gap-2 rounded-lg p-2 text-xs ${
msg.isFromMachine
? "bg-white/10"
: "bg-slate-200"
}`}
>
{getFileIcon(att.name)}
<span className="truncate">{att.name}</span>
{att.size && (
<span className="text-xs opacity-60">
({Math.round(att.size / 1024)}KB)
</span>
)}
</div>
))}
</div>
)}
<p
className={`mt-1 text-right text-xs ${
msg.isFromMachine ? "text-white/60" : "text-slate-400"
{/* Avatar */}
<div
className={`flex size-8 shrink-0 items-center justify-center rounded-full ${
isAgent ? "bg-black text-white" : "bg-slate-200 text-slate-600"
}`}
>
{formatTime(msg.createdAt)}
</p>
{isAgent ? <Headphones className="size-4" /> : <User className="size-4" />}
</div>
{/* Bubble */}
<div
className={`max-w-[75%] rounded-2xl px-4 py-2 ${
isAgent
? "rounded-br-md bg-black text-white"
: "rounded-bl-md border border-slate-100 bg-white text-slate-900 shadow-sm"
}`}
>
{!isAgent && (
<p className="mb-1 text-xs font-medium text-slate-500">
{msg.authorName}
</p>
)}
<p className="whitespace-pre-wrap text-sm">{msg.body}</p>
{/* Anexos */}
{msg.attachments && msg.attachments.length > 0 && (
<div className="mt-2 space-y-1">
{msg.attachments.map((att) => (
<div
key={att.storageId}
className={`flex items-center gap-2 rounded-lg p-2 text-xs ${
isAgent ? "bg-white/10" : "bg-slate-100"
}`}
>
{getFileIcon(att.name)}
<span className="truncate">{att.name}</span>
{att.size && (
<span className="text-xs opacity-60">
({Math.round(att.size / 1024)}KB)
</span>
)}
</div>
))}
</div>
)}
<p
className={`mt-1 text-right text-xs ${
isAgent ? "text-white/60" : "text-slate-400"
}`}
>
{formatTime(msg.createdAt)}
</p>
</div>
</div>
</div>
))}
)
})}
<div ref={messagesEndRef} />
</div>
)}