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:
parent
fd0e29514a
commit
7e270bcd3b
1 changed files with 61 additions and 48 deletions
|
|
@ -4,7 +4,7 @@ import { listen } from "@tauri-apps/api/event"
|
||||||
import { Store } from "@tauri-apps/plugin-store"
|
import { Store } from "@tauri-apps/plugin-store"
|
||||||
import { appLocalDataDir, join } from "@tauri-apps/api/path"
|
import { appLocalDataDir, join } from "@tauri-apps/api/path"
|
||||||
import { open } from "@tauri-apps/plugin-dialog"
|
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"
|
import type { ChatMessage, ChatMessagesResponse, SendMessageResponse } from "./types"
|
||||||
|
|
||||||
const STORE_FILENAME = "machine-agent.json"
|
const STORE_FILENAME = "machine-agent.json"
|
||||||
|
|
@ -381,58 +381,71 @@ export function ChatWidget({ ticketId }: ChatWidgetProps) {
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="space-y-3">
|
<div className="space-y-4">
|
||||||
{messages.map((msg) => (
|
{messages.map((msg) => {
|
||||||
<div
|
// No desktop: isFromMachine=true significa mensagem do cliente (maquina)
|
||||||
key={msg.id}
|
// Layout igual à web: cliente à esquerda, agente à direita
|
||||||
className={`flex ${msg.isFromMachine ? "justify-end" : "justify-start"}`}
|
const isAgent = !msg.isFromMachine
|
||||||
>
|
return (
|
||||||
<div
|
<div
|
||||||
className={`max-w-[80%] rounded-2xl px-4 py-2 ${
|
key={msg.id}
|
||||||
msg.isFromMachine
|
className={`flex gap-2 ${isAgent ? "flex-row-reverse" : "flex-row"}`}
|
||||||
? "bg-black text-white"
|
|
||||||
: "bg-slate-100 text-slate-900"
|
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
{!msg.isFromMachine && (
|
{/* Avatar */}
|
||||||
<p className="mb-1 text-xs font-medium text-slate-500">
|
<div
|
||||||
{msg.authorName}
|
className={`flex size-8 shrink-0 items-center justify-center rounded-full ${
|
||||||
</p>
|
isAgent ? "bg-black text-white" : "bg-slate-200 text-slate-600"
|
||||||
)}
|
|
||||||
<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"
|
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{formatTime(msg.createdAt)}
|
{isAgent ? <Headphones className="size-4" /> : <User className="size-4" />}
|
||||||
</p>
|
</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>
|
)
|
||||||
))}
|
})}
|
||||||
<div ref={messagesEndRef} />
|
<div ref={messagesEndRef} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue