Files
openchamber/packages/ui/src/hooks/usePushVisibilityBeacon.ts
T
Bohdan Triapitsyn 87d13cf61b fix: enable web runtime notifications without push (#1322)
Web notifications now listen to the notification stream directly
Native notifications no longer depend on PWA push being enabled
Window focus is respected when deciding whether to send background push notifications
2026-05-19 13:16:47 +03:00

67 lines
1.9 KiB
TypeScript

import React from 'react';
import { isWebRuntime } from '@/lib/desktop';
import { getRegisteredRuntimeAPIs } from '@/contexts/runtimeAPIRegistry';
const HEARTBEAT_MS = 20000;
const resolveVisibilityState = (): 'visible' | 'hidden' => {
if (typeof document === 'undefined') return 'visible';
return document.visibilityState === 'visible' && document.hasFocus() ? 'visible' : 'hidden';
};
const sendVisibility = (visible: boolean) => {
if (!isWebRuntime()) {
return;
}
const apis = getRegisteredRuntimeAPIs();
if (!apis?.push?.setVisibility) {
return;
}
void apis.push.setVisibility({ visible });
};
export const usePushVisibilityBeacon = (options?: { enabled?: boolean }) => {
const enabled = options?.enabled ?? true;
React.useEffect(() => {
if (!enabled || !isWebRuntime() || typeof document === 'undefined') {
return;
}
const report = () => {
sendVisibility(resolveVisibilityState() === 'visible');
};
const reportVisibleOnly = () => {
if (resolveVisibilityState() === 'visible') {
sendVisibility(true);
}
};
const reportPageHidden = () => {
sendVisibility(false);
};
report();
// Heartbeat while visible so server TTL (30s) never expires.
const interval = window.setInterval(reportVisibleOnly, HEARTBEAT_MS);
document.addEventListener('visibilitychange', report);
window.addEventListener('pagehide', reportPageHidden);
window.addEventListener('pageshow', report);
window.addEventListener('focus', report);
window.addEventListener('blur', report);
return () => {
window.clearInterval(interval);
document.removeEventListener('visibilitychange', report);
window.removeEventListener('pagehide', reportPageHidden);
window.removeEventListener('pageshow', report);
window.removeEventListener('focus', report);
window.removeEventListener('blur', report);
};
}, [enabled]);
};