fix(chat): correções de SSE, inicialização e área de clique

- Substituir WebSocket por SSE para real-time (chat.rs)
- Corrigir inicialização do chat runtime em lib.rs
- Iniciar unreadByMachine em 0 ao criar sessão (liveChat.ts)
- Corrigir área de clique do chip minimizado (pointer-events)
- Corrigir roteamento SPA no Tauri (index.html?view=chat)
- Corrigir estado inicial isMinimized como true

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
rever-tecnologia 2025-12-09 11:51:33 -03:00
parent 3aee1a6694
commit 3c2d1824fb
7 changed files with 213 additions and 256 deletions

View file

@ -50,7 +50,8 @@ export function ChatWidget({ ticketId }: ChatWidgetProps) {
const [ticketInfo, setTicketInfo] = useState<{ ref: number; subject: string; agentName: string } | null>(null)
const [hasSession, setHasSession] = useState(false)
const [pendingAttachments, setPendingAttachments] = useState<UploadedAttachment[]>([])
const [isMinimized, setIsMinimized] = useState(false)
// Inicializa minimizado porque o Rust abre a janela e minimiza imediatamente
const [isMinimized, setIsMinimized] = useState(true)
const [unreadCount, setUnreadCount] = useState(0)
const messagesEndRef = useRef<HTMLDivElement>(null)
@ -235,18 +236,26 @@ export function ChatWidget({ ticketId }: ChatWidgetProps) {
}
if (isLoading) {
// Mostrar chip compacto enquanto carrega (compativel com janela minimizada)
// pointer-events-none no container para que a area transparente nao seja clicavel
return (
<div className="flex h-screen flex-col items-center justify-center bg-white">
<Loader2 className="size-8 animate-spin text-slate-400" />
<p className="mt-2 text-sm text-slate-500">Carregando chat...</p>
<div className="pointer-events-none flex h-full w-full items-end justify-end bg-transparent p-2">
<div className="pointer-events-auto flex items-center gap-2 rounded-full bg-slate-200 px-4 py-2 text-slate-600 shadow-lg">
<Loader2 className="size-4 animate-spin" />
<span className="text-sm font-medium">Carregando...</span>
</div>
</div>
)
}
if (error) {
// Mostrar chip compacto de erro (compativel com janela minimizada)
return (
<div className="flex h-screen flex-col items-center justify-center bg-white p-4">
<p className="text-sm text-red-600">{error}</p>
<div className="pointer-events-none flex h-full w-full items-end justify-end bg-transparent p-2">
<div className="pointer-events-auto flex items-center gap-2 rounded-full bg-red-100 px-4 py-2 text-red-600 shadow-lg">
<X className="size-4" />
<span className="text-sm font-medium">Erro no chat</span>
</div>
</div>
)
}
@ -254,8 +263,8 @@ export function ChatWidget({ ticketId }: ChatWidgetProps) {
// Quando não há sessão, mostrar versão minimizada com indicador de offline
if (!hasSession) {
return (
<div className="flex h-full w-full items-end justify-end bg-transparent">
<div className="flex items-center gap-2 rounded-full bg-slate-200 px-4 py-2 text-slate-600 shadow-lg">
<div className="pointer-events-none flex h-full w-full items-end justify-end bg-transparent">
<div className="pointer-events-auto flex items-center gap-2 rounded-full bg-slate-200 px-4 py-2 text-slate-600 shadow-lg">
<MessageCircle className="size-4" />
<span className="text-sm font-medium">
{ticketInfo ? `Chat #${ticketInfo.ref}` : "Chat"}
@ -268,12 +277,13 @@ export function ChatWidget({ ticketId }: ChatWidgetProps) {
}
// Versão minimizada (chip compacto igual web)
// pointer-events-none no container para que apenas o botao seja clicavel
if (isMinimized) {
return (
<div className="flex h-full w-full items-end justify-end bg-transparent">
<div className="pointer-events-none flex h-full w-full items-end justify-end bg-transparent">
<button
onClick={handleExpand}
className="relative flex items-center gap-2 rounded-full bg-black px-4 py-2 text-white shadow-lg hover:bg-black/90"
className="pointer-events-auto relative flex items-center gap-2 rounded-full bg-black px-4 py-2 text-white shadow-lg hover:bg-black/90"
>
<MessageCircle className="size-4" />
<span className="text-sm font-medium">

View file

@ -1728,12 +1728,13 @@ function StatusBadge({ status, className }: { status: string | null; className?:
)
}
// Roteamento simples baseado no path
// Roteamento simples baseado em query params (compativel com Tauri SPA)
function RootApp() {
const path = window.location.pathname
const params = new URLSearchParams(window.location.search)
const view = params.get("view")
// Rota /chat - janela de chat flutuante
if (path === "/chat" || path.startsWith("/chat?")) {
// Janela de chat flutuante (view=chat ou path=/chat para compatibilidade)
if (view === "chat" || window.location.pathname === "/chat") {
return <ChatApp />
}