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:
parent
366bc4bf12
commit
082f2d67f1
1 changed files with 19 additions and 25 deletions
|
|
@ -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
|
||||
setIsOpen(state.isOpen)
|
||||
setIsMinimized(state.isMinimized)
|
||||
if (state.activeTicketId) {
|
||||
setActiveTicketId(state.activeTicketId)
|
||||
}
|
||||
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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue