fix: corrige sincronizacao de estado do chat entre abas

O BroadcastChannel nao estava funcionando corretamente porque
cada aba restaurava do localStorage independentemente na montagem.

Mudanca:
- Substituido BroadcastChannel pelo evento 'storage' do localStorage
- O evento storage dispara automaticamente em TODAS as outras abas
  quando o localStorage e alterado (mais confiavel)
- Removido broadcastChannelRef e CHAT_WIDGET_CHANNEL nao mais usados

Comportamento:
- Abrir/fechar/minimizar chat em uma aba sincroniza com todas as outras
- Estado persiste entre reloads via localStorage

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
rever-tecnologia 2025-12-11 15:48:33 -03:00
parent 366bc4bf12
commit 082f2d67f1

View file

@ -38,7 +38,6 @@ import {
const MAX_MESSAGE_LENGTH = 4000
const MAX_ATTACHMENT_SIZE = 5 * 1024 * 1024 // 5MB
const MAX_ATTACHMENTS = 5
const CHAT_WIDGET_CHANNEL = "chat-widget-sync"
const STORAGE_KEY = "chat-widget-state"
type ChatWidgetState = {
@ -281,7 +280,6 @@ export function ChatWidget() {
return null
})
const [draft, setDraft] = useState("")
const broadcastChannelRef = useRef<BroadcastChannel | null>(null)
const [isSending, setIsSending] = useState(false)
const [isEndingChat, setIsEndingChat] = useState(false)
const [attachments, setAttachments] = useState<UploadedFile[]>([])
@ -320,31 +318,32 @@ export function ChatWidget() {
const machineOnline = liveChat?.machineOnline ?? false
const machineHostname = liveChat?.machineHostname
// Sincronizar estado entre abas usando BroadcastChannel
// Sincronizar estado entre abas usando evento storage do localStorage
// O evento storage dispara automaticamente em TODAS as outras abas quando localStorage muda
useEffect(() => {
if (typeof window === "undefined") return
// Criar canal de broadcast
const channel = new BroadcastChannel(CHAT_WIDGET_CHANNEL)
broadcastChannelRef.current = channel
const handleStorageChange = (event: StorageEvent) => {
// Ignorar mudancas em outras chaves
if (event.key !== STORAGE_KEY) return
// Ignorar se nao tem valor novo
if (!event.newValue) return
// Ouvir mensagens de outras abas
channel.onmessage = (event: MessageEvent<ChatWidgetState>) => {
const state = event.data
try {
const state = JSON.parse(event.newValue) as ChatWidgetState
setIsOpen(state.isOpen)
setIsMinimized(state.isMinimized)
if (state.activeTicketId) {
setActiveTicketId(state.activeTicketId)
}
} catch {}
}
return () => {
channel.close()
broadcastChannelRef.current = null
}
window.addEventListener("storage", handleStorageChange)
return () => window.removeEventListener("storage", handleStorageChange)
}, [])
// Salvar estado no localStorage e broadcast para outras abas quando muda
// Salvar estado no localStorage quando muda (dispara evento storage em outras abas)
useEffect(() => {
if (typeof window === "undefined") return
@ -354,15 +353,10 @@ export function ChatWidget() {
activeTicketId,
}
// Salvar no localStorage para persistir entre reloads
// Salvar no localStorage (isso dispara evento storage em outras abas automaticamente)
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(state))
} catch {}
// Broadcast para outras abas
if (broadcastChannelRef.current) {
broadcastChannelRef.current.postMessage(state)
}
}, [isOpen, isMinimized, activeTicketId])
// Auto-selecionar primeira sessão se nenhuma selecionada