fix: corrige contador de mensagens nao lidas e chat desktop abrindo expandido
- Web: adiciona ref hasMarkedReadRef para evitar chamadas duplicadas ao markChatRead e garante que mensagens sejam marcadas como lidas mesmo quando o chat carrega apos isOpen se tornar true - Desktop: aumenta periodo de estabilizacao do resize handler para 500ms, evitando que eventos transitórios alterem o estado isMinimized 🤖 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
082f2d67f1
commit
efc3af3fde
2 changed files with 49 additions and 14 deletions
|
|
@ -133,12 +133,15 @@ export function ChatWidget({ ticketId, ticketRef }: ChatWidgetProps) {
|
||||||
// Sincroniza estado de minimizado com o tamanho da janela (apenas em resizes reais, nao na montagem)
|
// Sincroniza estado de minimizado com o tamanho da janela (apenas em resizes reais, nao na montagem)
|
||||||
// O estado inicial isMinimized=true e definido no useState e nao deve ser sobrescrito na montagem
|
// O estado inicial isMinimized=true e definido no useState e nao deve ser sobrescrito na montagem
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let isFirstRender = true
|
// Ignorar todos os eventos de resize nos primeiros 500ms apos a montagem
|
||||||
|
// Isso da tempo ao Tauri de aplicar o tamanho correto da janela
|
||||||
|
// e evita que resizes transitórios durante a criação da janela alterem o estado
|
||||||
|
const mountTime = Date.now()
|
||||||
|
const STABILIZATION_DELAY = 500 // ms para a janela estabilizar
|
||||||
|
|
||||||
const handler = () => {
|
const handler = () => {
|
||||||
// Ignorar a primeira chamada para preservar o estado inicial (isMinimized=true)
|
// Ignorar eventos de resize durante o periodo de estabilizacao
|
||||||
// Isso evita condicao de corrida onde window.innerHeight pode estar incorreto antes do Tauri aplicar o tamanho
|
if (Date.now() - mountTime < STABILIZATION_DELAY) {
|
||||||
if (isFirstRender) {
|
|
||||||
isFirstRender = false
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const h = window.innerHeight
|
const h = window.innerHeight
|
||||||
|
|
|
||||||
|
|
@ -401,22 +401,54 @@ export function ChatWidget() {
|
||||||
}
|
}
|
||||||
}, [messages.length, isOpen, isMinimized])
|
}, [messages.length, isOpen, isMinimized])
|
||||||
|
|
||||||
// Marcar mensagens como lidas ao abrir/mostrar chat
|
// Ref para rastrear se ja marcamos como lidas nesta abertura do chat
|
||||||
|
const hasMarkedReadRef = useRef<boolean>(false)
|
||||||
|
|
||||||
|
// Reset da flag quando fecha ou minimiza o chat
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!viewerId || !chat || !activeTicketId) return
|
if (!isOpen || isMinimized) {
|
||||||
// Só marca quando o widget está aberto, expandido e a aba está ativa
|
hasMarkedReadRef.current = false
|
||||||
|
}
|
||||||
|
}, [isOpen, isMinimized])
|
||||||
|
|
||||||
|
// Marcar mensagens como lidas ao abrir/mostrar chat
|
||||||
|
// Usa um pequeno delay para garantir que o chat carregou
|
||||||
|
useEffect(() => {
|
||||||
|
// So marca quando o widget esta aberto, expandido e a aba esta ativa
|
||||||
if (!isOpen || isMinimized) return
|
if (!isOpen || isMinimized) return
|
||||||
|
if (!viewerId || !activeTicketId) return
|
||||||
if (typeof document !== "undefined" && document.visibilityState === "hidden") return
|
if (typeof document !== "undefined" && document.visibilityState === "hidden") return
|
||||||
|
|
||||||
|
// Se ainda nao temos chat carregado, aguardar
|
||||||
|
if (!chat) return
|
||||||
|
|
||||||
|
// Evitar marcar multiplas vezes na mesma abertura
|
||||||
|
if (hasMarkedReadRef.current) return
|
||||||
|
|
||||||
const unreadIds = chat.messages
|
const unreadIds = chat.messages
|
||||||
?.filter((msg) => !msg.readBy?.some((r) => r.userId === viewerId))
|
?.filter((msg) => !msg.readBy?.some((r) => r.userId === viewerId))
|
||||||
.map((msg) => msg.id) ?? []
|
.map((msg) => msg.id) ?? []
|
||||||
if (unreadIds.length === 0) return
|
|
||||||
markChatRead({
|
if (unreadIds.length === 0) {
|
||||||
ticketId: activeTicketId as Id<"tickets">,
|
// Mesmo sem mensagens nao lidas, marcar que ja processamos
|
||||||
actorId: viewerId as Id<"users">,
|
hasMarkedReadRef.current = true
|
||||||
messageIds: unreadIds,
|
return
|
||||||
}).catch(console.error)
|
}
|
||||||
|
|
||||||
|
// Marcar como lidas com pequeno delay para garantir estabilidade
|
||||||
|
const timeoutId = setTimeout(() => {
|
||||||
|
markChatRead({
|
||||||
|
ticketId: activeTicketId as Id<"tickets">,
|
||||||
|
actorId: viewerId as Id<"users">,
|
||||||
|
messageIds: unreadIds,
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
hasMarkedReadRef.current = true
|
||||||
|
})
|
||||||
|
.catch(console.error)
|
||||||
|
}, 100)
|
||||||
|
|
||||||
|
return () => clearTimeout(timeoutId)
|
||||||
}, [viewerId, chat, activeTicketId, isOpen, isMinimized, markChatRead])
|
}, [viewerId, chat, activeTicketId, isOpen, isMinimized, markChatRead])
|
||||||
|
|
||||||
// Upload de arquivos
|
// Upload de arquivos
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue