Rebranded for Thunderbird Portal (THBD): numbering prefix EL->TH, all "ELMI"/"ЭЛМИ" UI strings genericized, ELMI's real contract templates and company legal/bank details removed (not applicable to this company), fresh VAPID keypair and encryption key, fresh single-migration schema history. Same architecture as elmi-portal: Web Push notifications, unread-chat app badge, cookie-session auth. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Gh2UXUQUVBWroWEnn1FLFG
26 lines
773 B
TypeScript
26 lines
773 B
TypeScript
"use client";
|
||
|
||
import { useEffect } from "react";
|
||
|
||
const INTERVAL_MS = 20_000;
|
||
|
||
/** Держит lastSeenAt свежим, пока вкладка открыта и видима — "онлайн" на клиенте вычисляется как lastSeenAt моложе ~30с. */
|
||
export function PresenceHeartbeat() {
|
||
useEffect(() => {
|
||
function ping() {
|
||
if (document.visibilityState === "visible") {
|
||
fetch("/api/presence/heartbeat", { method: "POST" }).catch(() => {});
|
||
}
|
||
}
|
||
ping();
|
||
const interval = setInterval(ping, INTERVAL_MS);
|
||
document.addEventListener("visibilitychange", ping);
|
||
return () => {
|
||
clearInterval(interval);
|
||
document.removeEventListener("visibilitychange", ping);
|
||
};
|
||
}, []);
|
||
|
||
return null;
|
||
}
|