feat: enhance chat components with improved accessibility features, including ARIA attributes for search and user status, and implement message length validation and file type checks in message input handling
This commit is contained in:
@@ -17,6 +17,47 @@
|
||||
let heartbeatInterval: ReturnType<typeof setInterval> | null = null;
|
||||
let inactivityTimeout: ReturnType<typeof setTimeout> | null = null;
|
||||
let lastActivity = Date.now();
|
||||
let lastStatusUpdate = 0;
|
||||
let pendingStatusUpdate: ReturnType<typeof setTimeout> | null = null;
|
||||
const STATUS_UPDATE_THROTTLE = 5000; // 5 segundos entre atualizações
|
||||
|
||||
// Função auxiliar para atualizar status com throttle e tratamento de erro
|
||||
async function atualizarStatusPresencaSeguro(status: 'online' | 'offline' | 'ausente' | 'externo' | 'em_reuniao') {
|
||||
if (!usuarioAutenticado) return;
|
||||
|
||||
const now = Date.now();
|
||||
// Throttle: só atualizar se passou tempo suficiente desde a última atualização
|
||||
if (now - lastStatusUpdate < STATUS_UPDATE_THROTTLE) {
|
||||
// Cancelar atualização pendente se houver
|
||||
if (pendingStatusUpdate) {
|
||||
clearTimeout(pendingStatusUpdate);
|
||||
}
|
||||
// Agendar atualização para depois do throttle
|
||||
pendingStatusUpdate = setTimeout(() => {
|
||||
atualizarStatusPresencaSeguro(status);
|
||||
}, STATUS_UPDATE_THROTTLE - (now - lastStatusUpdate));
|
||||
return;
|
||||
}
|
||||
|
||||
// Limpar atualização pendente se houver
|
||||
if (pendingStatusUpdate) {
|
||||
clearTimeout(pendingStatusUpdate);
|
||||
pendingStatusUpdate = null;
|
||||
}
|
||||
|
||||
lastStatusUpdate = now;
|
||||
|
||||
try {
|
||||
await client.mutation(api.chat.atualizarStatusPresenca, { status });
|
||||
} catch (error) {
|
||||
// Silenciar erros de timeout - não são críticos para a funcionalidade
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
const isTimeout = errorMessage.includes('timed out') || errorMessage.includes('timeout');
|
||||
if (!isTimeout) {
|
||||
console.error('Erro ao atualizar status de presença:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Detectar atividade do usuário
|
||||
function handleActivity() {
|
||||
@@ -33,7 +74,7 @@
|
||||
inactivityTimeout = setTimeout(
|
||||
() => {
|
||||
if (usuarioAutenticado) {
|
||||
client.mutation(api.chat.atualizarStatusPresenca, { status: 'ausente' });
|
||||
atualizarStatusPresencaSeguro('ausente');
|
||||
}
|
||||
},
|
||||
5 * 60 * 1000
|
||||
@@ -45,7 +86,7 @@
|
||||
if (!usuarioAutenticado) return;
|
||||
|
||||
// Configurar como online ao montar (apenas se autenticado)
|
||||
client.mutation(api.chat.atualizarStatusPresenca, { status: 'online' });
|
||||
atualizarStatusPresencaSeguro('online');
|
||||
|
||||
// Heartbeat a cada 30 segundos (apenas se autenticado)
|
||||
heartbeatInterval = setInterval(() => {
|
||||
@@ -61,7 +102,7 @@
|
||||
|
||||
// Se houve atividade nos últimos 5 minutos, manter online
|
||||
if (timeSinceLastActivity < 5 * 60 * 1000) {
|
||||
client.mutation(api.chat.atualizarStatusPresenca, { status: 'online' });
|
||||
atualizarStatusPresencaSeguro('online');
|
||||
}
|
||||
}, 30 * 1000);
|
||||
|
||||
@@ -82,10 +123,10 @@
|
||||
|
||||
if (document.hidden) {
|
||||
// Aba ficou inativa
|
||||
client.mutation(api.chat.atualizarStatusPresenca, { status: 'ausente' });
|
||||
atualizarStatusPresencaSeguro('ausente');
|
||||
} else {
|
||||
// Aba ficou ativa
|
||||
client.mutation(api.chat.atualizarStatusPresenca, { status: 'online' });
|
||||
atualizarStatusPresencaSeguro('online');
|
||||
handleActivity();
|
||||
}
|
||||
}
|
||||
@@ -94,9 +135,15 @@
|
||||
|
||||
// Cleanup
|
||||
return () => {
|
||||
// Limpar atualização pendente
|
||||
if (pendingStatusUpdate) {
|
||||
clearTimeout(pendingStatusUpdate);
|
||||
pendingStatusUpdate = null;
|
||||
}
|
||||
|
||||
// Marcar como offline ao desmontar (apenas se autenticado)
|
||||
if (usuarioAutenticado) {
|
||||
client.mutation(api.chat.atualizarStatusPresenca, { status: 'offline' });
|
||||
atualizarStatusPresencaSeguro('offline');
|
||||
}
|
||||
|
||||
if (heartbeatInterval) {
|
||||
|
||||
Reference in New Issue
Block a user