Melhora UX do chat no desktop
All checks were successful
CI/CD Web + Desktop / Detect changes (push) Successful in 7s
CI/CD Web + Desktop / Deploy (VPS Linux) (push) Successful in 3m41s
CI/CD Web + Desktop / Deploy Convex functions (push) Has been skipped
Quality Checks / Lint, Test and Build (push) Successful in 4m5s

This commit is contained in:
rever-tecnologia 2025-12-18 23:53:24 -03:00
parent 9142446f06
commit 0a0f722bd8
4 changed files with 82 additions and 7 deletions

View file

@ -277,6 +277,8 @@ export function ChatWidget({ ticketId, ticketRef }: ChatWidgetProps) {
| { type: "message"; messageId: string; behavior: ScrollBehavior; markRead: boolean }
| null
>(null)
const autoReadInFlightRef = useRef(false)
const lastAutoReadCountRef = useRef<number | null>(null)
const unreadAgentMessageIds = useMemo(() => getUnreadAgentMessageIds(messages, unreadCount), [messages, unreadCount])
const firstUnreadAgentMessageId = unreadAgentMessageIds[0] ?? null
@ -374,9 +376,9 @@ export function ChatWidget({ ticketId, ticketRef }: ChatWidgetProps) {
}, [apiBaseUrl, machineToken, ticketId])
const markUnreadMessagesRead = useCallback(async () => {
if (unreadCount <= 0) return
if (unreadCount <= 0) return false
const ids = getUnreadAgentMessageIds(messages, unreadCount)
if (ids.length === 0) return
if (ids.length === 0) return false
const chunks = chunkArray(ids, MARK_READ_BATCH_SIZE)
for (const chunk of chunks) {
@ -385,8 +387,26 @@ export function ChatWidget({ ticketId, ticketRef }: ChatWidgetProps) {
messageIds: chunk as Id<"ticketChatMessages">[],
})
}
return true
}, [messages, ticketId, unreadCount, markMessagesRead])
const maybeAutoMarkRead = useCallback(async () => {
if (autoReadInFlightRef.current) return
if (!hasSession || unreadCount <= 0) return
if (isMinimizedRef.current || !isAtBottomRef.current) return
if (lastAutoReadCountRef.current === unreadCount) return
autoReadInFlightRef.current = true
try {
const didMark = await markUnreadMessagesRead()
if (didMark) {
lastAutoReadCountRef.current = unreadCount
}
} finally {
autoReadInFlightRef.current = false
}
}, [hasSession, unreadCount, markUnreadMessagesRead])
// Auto-scroll quando novas mensagens chegam (se ja estava no bottom)
const prevMessagesLengthRef = useRef(messages.length)
useEffect(() => {
@ -430,6 +450,14 @@ export function ChatWidget({ ticketId, ticketRef }: ChatWidgetProps) {
}
}, [isMinimized, messages, markUnreadMessagesRead, scrollToBottom, scrollToMessage])
useEffect(() => {
if (unreadCount === 0) {
lastAutoReadCountRef.current = null
return
}
maybeAutoMarkRead().catch((err) => console.error("Falha ao auto-marcar mensagens:", err))
}, [isMinimized, isAtBottom, unreadCount, maybeAutoMarkRead])
// Sincronizar estado minimizado com tamanho da janela
useEffect(() => {
const mountTime = Date.now()
@ -538,7 +566,7 @@ export function ChatWidget({ ticketId, ticketRef }: ChatWidgetProps) {
setIsMinimized(false)
try {
await invoke("set_chat_minimized", { ticketId, minimized: false })
await invoke("open_chat_window", { ticketId, ticketRef: ticketRef ?? 0 })
} catch (err) {
console.error("Erro ao expandir janela:", err)
}