- 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.
90 lines
2.7 KiB
Svelte
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 -->
|
|
|