Files
sgse-app/apps/web/src/lib/components/chat/PresenceManager.svelte
killer-cf 9a5f2b294d refactor: integrate current user data across components
- Replaced instances of `authStore` with `currentUser` to streamline user authentication handling.
- Updated permission checks and user-related data retrieval to utilize the new `useQuery` for better performance and clarity.
- Cleaned up component structures and improved formatting for consistency and readability.
- Enhanced error handling and user feedback mechanisms in various components to improve user experience.
2025-11-08 10:52:33 -03:00

90 lines
2.7 KiB
Svelte

<script lang="ts">
import { useConvexClient } from "convex-svelte";
import { api } from "@sgse-app/backend/convex/_generated/api";
import { onMount } from "svelte";
const client = useConvexClient();
// Token é passado automaticamente via interceptadores em +layout.svelte
let heartbeatInterval: ReturnType<typeof setInterval> | null = null;
let inactivityTimeout: ReturnType<typeof setTimeout> | null = null;
let lastActivity = Date.now();
// Detectar atividade do usuário
function handleActivity() {
lastActivity = Date.now();
// Limpar timeout de inatividade anterior
if (inactivityTimeout) {
clearTimeout(inactivityTimeout);
}
// Configurar novo timeout (5 minutos)
inactivityTimeout = setTimeout(() => {
client.mutation(api.chat.atualizarStatusPresenca, { status: "ausente" });
}, 5 * 60 * 1000);
}
onMount(() => {
// Configurar como online ao montar
client.mutation(api.chat.atualizarStatusPresenca, { status: "online" });
// Heartbeat a cada 30 segundos
heartbeatInterval = setInterval(() => {
const timeSinceLastActivity = Date.now() - lastActivity;
// Se houve atividade nos últimos 5 minutos, manter online
if (timeSinceLastActivity < 5 * 60 * 1000) {
client.mutation(api.chat.atualizarStatusPresenca, { status: "online" });
}
}, 30 * 1000);
// Listeners para detectar atividade
const events = ["mousedown", "keydown", "scroll", "touchstart"];
events.forEach((event) => {
window.addEventListener(event, handleActivity);
});
// Configurar timeout inicial de inatividade
handleActivity();
// Detectar quando a aba fica inativa/ativa
function handleVisibilityChange() {
if (document.hidden) {
// Aba ficou inativa
client.mutation(api.chat.atualizarStatusPresenca, { status: "ausente" });
} else {
// Aba ficou ativa
client.mutation(api.chat.atualizarStatusPresenca, { status: "online" });
handleActivity();
}
}
document.addEventListener("visibilitychange", handleVisibilityChange);
// Cleanup
return () => {
// Marcar como offline ao desmontar
client.mutation(api.chat.atualizarStatusPresenca, { status: "offline" });
if (heartbeatInterval) {
clearInterval(heartbeatInterval);
}
if (inactivityTimeout) {
clearTimeout(inactivityTimeout);
}
events.forEach((event) => {
window.removeEventListener(event, handleActivity);
});
document.removeEventListener("visibilitychange", handleVisibilityChange);
};
});
</script>
<!-- Componente invisível - apenas lógica -->