import { useEffect } from 'react'; import { useSetAtom } from 'jotai'; import { focusAssistActiveAtom } from '../state/focusAssist'; import { tauriInvoke, useTauriEvent } from './useTauri'; /** Detail shape of the `focus-assist-changed` event emitted by the native side. */ type FocusAssistChangedDetail = { active: boolean; }; /** * P5-56 — Windows Focus Assist ↔ Do-Not-Disturb sync (desktop). Subscribes to * the native `focus-assist-changed` event (Windows `SHQueryUserNotificationState` * poll, `{ active }`) and mirrors it into `focusAssistActiveAtom`, which the * notification gate reads to suppress notifications while the shell is in Focus * Assist / Quiet Hours, presenting, gaming full-screen, or busy. Inert in the * browser, since `useTauriEvent` only listens under Tauri. */ export function useTauriFocusAssist(): void { const setFocusAssist = useSetAtom(focusAssistActiveAtom); useTauriEvent('focus-assist-changed', ({ active }) => setFocusAssist(active), ); // Hydrate on mount. The native poll only emits on a transition, and its first // reading lands during app setup before this page is listening — so with Focus // Assist already on at launch (or after a reload) notifications leaked until // the OS state next flipped (cinny-desktop #15). `null` = no reading yet. useEffect(() => { tauriInvoke()?.('get_focus_assist') .then((active) => { if (typeof active === 'boolean') setFocusAssist(active); }) .catch(() => undefined); }, [setFocusAssist]); }