Changes again

This commit is contained in:
Andras Schmelczer 2026-03-15 21:14:50 +00:00
parent f4de0eeb9f
commit 479ef92236
4 changed files with 160 additions and 95 deletions

View file

@ -0,0 +1,58 @@
import { useEffect, useRef } from 'react';
import { apiUrl } from '../lib/api';
/**
* Sends a telemetry beacon every 30 seconds with session duration
* and the number of active filters (parsed from the URL `f` param).
* On the first beacon, also sends the entry path and referrer domain.
*/
export function useTelemetry() {
const startTime = useRef(Date.now());
const entryPath = useRef(window.location.pathname);
const referrer = useRef(extractReferrerDomain());
const sentEntry = useRef(false);
useEffect(() => {
const send = () => {
const sessionSeconds = Math.round((Date.now() - startTime.current) / 1000);
// Count active filters from URL (filters are encoded as `f=name:min:max;;name:val`)
const params = new URLSearchParams(window.location.search);
const filterStr = params.get('f') || '';
const filterCount = filterStr ? filterStr.split(';;').length : 0;
const payload: Record<string, unknown> = {
session_seconds: sessionSeconds,
filter_count: filterCount,
};
// Include entrypoint info on first beacon only
if (!sentEntry.current) {
payload.entry_path = entryPath.current;
payload.referrer = referrer.current;
sentEntry.current = true;
}
navigator.sendBeacon(
apiUrl('telemetry'),
new Blob([JSON.stringify(payload)], { type: 'application/json' })
);
};
const interval = setInterval(send, 30_000);
return () => clearInterval(interval);
}, []);
}
/** Extract the referrer domain, or "direct" if none / same-origin. */
function extractReferrerDomain(): string {
if (!document.referrer) return 'direct';
try {
const url = new URL(document.referrer);
// Same-origin navigation isn't a real external referrer
if (url.origin === window.location.origin) return 'direct';
return url.hostname;
} catch {
return 'direct';
}
}