fix: corrige chat reabrindo sozinho e melhora mensagens

- Remove window.show() que forçava chat reabrir a cada polling
- Chat só abre minimizado quando há NOVAS mensagens (janela não existia)
- Se usuário fechou o chat, não reabre automaticamente
- Corrige acentuação: "Voce" → "Você", "nao" → "não"
- Simplifica toast para "Chat ao vivo iniciado"
- Melhora mensagem de erro quando máquina está offline
- Loga erro técnico no console ao invés de exibir para usuário

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Seu Nome 2025-12-08 12:22:44 -03:00
parent e66b3cce92
commit 0afdba1635
6 changed files with 33 additions and 16 deletions

View file

@ -818,26 +818,23 @@ async fn process_chat_update(
); );
// Mostrar janela de chat minimizada (menos intrusivo que abrir completo) // Mostrar janela de chat minimizada (menos intrusivo que abrir completo)
// Só abre se a janela não existir - se usuário fechou, não reabre automaticamente
if let Some(session) = current_sessions.first() { if let Some(session) = current_sessions.first() {
// Abrir janela se nao existir
let label = format!("chat-{}", session.ticket_id); let label = format!("chat-{}", session.ticket_id);
if app.get_webview_window(&label).is_none() { if app.get_webview_window(&label).is_none() {
let _ = open_chat_window(app, &session.ticket_id); let _ = open_chat_window(app, &session.ticket_id);
// Minimizar imediatamente apos abrir // Minimizar imediatamente após abrir
let _ = set_chat_minimized(app, &session.ticket_id, true); let _ = set_chat_minimized(app, &session.ticket_id, true);
} }
// Se ja existe, apenas garantir que esta visivel (pode estar escondida) // Se janela já existe, não força reabrir - respeita decisão do usuário
else if let Some(window) = app.get_webview_window(&label) {
let _ = window.show();
}
} }
// Notificacao nativa // Notificacao nativa
let notification_title = "Nova mensagem de suporte"; let notification_title = "Nova mensagem de suporte";
let notification_body = if new_count == 1 { let notification_body = if new_count == 1 {
"Voce recebeu 1 nova mensagem no chat".to_string() "Você recebeu 1 nova mensagem no chat".to_string()
} else { } else {
format!("Voce recebeu {} novas mensagens no chat", new_count) format!("Você recebeu {} novas mensagens no chat", new_count)
}; };
let _ = app let _ = app
.notification() .notification()
@ -929,7 +926,7 @@ pub fn minimize_chat_window(app: &tauri::AppHandle, ticket_id: &str) -> Result<(
/// Redimensiona a janela de chat para modo minimizado (chip) ou expandido /// Redimensiona a janela de chat para modo minimizado (chip) ou expandido
pub fn set_chat_minimized(app: &tauri::AppHandle, ticket_id: &str, minimized: bool) -> Result<(), String> { pub fn set_chat_minimized(app: &tauri::AppHandle, ticket_id: &str, minimized: bool) -> Result<(), String> {
let label = format!("chat-{}", ticket_id); let label = format!("chat-{}", ticket_id);
let window = app.get_webview_window(&label).ok_or("Janela nao encontrada")?; let window = app.get_webview_window(&label).ok_or("Janela não encontrada")?;
// Tamanhos - chip minimizado com margem extra para badge (absolute -top-1 -right-1) // Tamanhos - chip minimizado com margem extra para badge (absolute -top-1 -right-1)
let (width, height) = if minimized { let (width, height) = if minimized {

View file

@ -302,7 +302,7 @@ export function ChatWidget({ ticketId }: ChatWidgetProps) {
setMessages(prev => [...prev, { setMessages(prev => [...prev, {
id: response.messageId, id: response.messageId,
body: messageText || (attachmentsToSend.length > 0 ? "[Anexo]" : ""), body: messageText || (attachmentsToSend.length > 0 ? "[Anexo]" : ""),
authorName: "Voce", authorName: "Você",
isFromMachine: true, isFromMachine: true,
createdAt: response.createdAt, createdAt: response.createdAt,
attachments: attachmentsToSend.map(a => ({ attachments: attachmentsToSend.map(a => ({

View file

@ -8,7 +8,7 @@ export function ChatApp() {
if (!ticketId) { if (!ticketId) {
return ( return (
<div className="flex h-screen flex-col items-center justify-center bg-white p-4"> <div className="flex h-screen flex-col items-center justify-center bg-white p-4">
<p className="text-sm text-red-600">Erro: ticketId nao fornecido</p> <p className="text-sm text-red-600">Erro: ticketId não fornecido</p>
</div> </div>
) )
} }

View file

@ -172,7 +172,7 @@ export function ChatFloatingWidget({
setMessages(prev => [...prev, { setMessages(prev => [...prev, {
id: response.messageId, id: response.messageId,
body: messageText, body: messageText,
authorName: "Voce", authorName: "Você",
isFromMachine: true, isFromMachine: true,
createdAt: response.createdAt, createdAt: response.createdAt,
attachments: [], attachments: [],

View file

@ -138,7 +138,17 @@ export function TicketChatPanel({ ticketId }: TicketChatPanelProps) {
toast.info("Já existe uma sessão de chat ativa", { id: "live-chat" }) toast.info("Já existe uma sessão de chat ativa", { id: "live-chat" })
} }
} catch (error: unknown) { } catch (error: unknown) {
const message = error instanceof Error ? error.message : "Não foi possível iniciar o chat" console.error("[LiveChat] Erro ao iniciar chat:", error)
// Extrair mensagem amigável do erro do Convex
let message = "Não foi possível iniciar o chat"
if (error instanceof Error) {
const errorMsg = error.message.toLowerCase()
if (errorMsg.includes("offline")) {
message = "Máquina offline. Aguarde a máquina ficar online para iniciar o chat."
} else if (errorMsg.includes("não encontrad") || errorMsg.includes("not found")) {
message = "Máquina não encontrada"
}
}
toast.error(message, { id: "live-chat" }) toast.error(message, { id: "live-chat" })
} finally { } finally {
setIsStartingChat(false) setIsStartingChat(false)

View file

@ -351,12 +351,22 @@ export function TicketSummaryHeader({ ticket }: TicketHeaderProps) {
actorId: convexUserId as Id<"users">, actorId: convexUserId as Id<"users">,
}) })
if (result.isNew) { if (result.isNew) {
toast.success("Chat ao vivo iniciado! O cliente será notificado.", { id: "live-chat" }) toast.success("Chat ao vivo iniciado", { id: "live-chat" })
} else { } else {
toast.info("Já existe uma sessão de chat ativa.", { id: "live-chat" }) toast.info("Já existe uma sessão de chat ativa", { id: "live-chat" })
} }
} catch (error: unknown) { } catch (error: unknown) {
const message = error instanceof Error ? error.message : "Não foi possível iniciar o chat" console.error("[LiveChat] Erro ao iniciar chat:", error)
// Extrair mensagem amigável do erro do Convex
let message = "Não foi possível iniciar o chat"
if (error instanceof Error) {
const errorMsg = error.message.toLowerCase()
if (errorMsg.includes("offline")) {
message = "Máquina offline. Aguarde a máquina ficar online para iniciar o chat."
} else if (errorMsg.includes("não encontrad") || errorMsg.includes("not found")) {
message = "Máquina não encontrada"
}
}
toast.error(message, { id: "live-chat" }) toast.error(message, { id: "live-chat" })
} finally { } finally {
setIsStartingChat(false) setIsStartingChat(false)