Files
cinny/src/app/hooks/useTauriFocusAssist.ts
T

38 lines
1.5 KiB
TypeScript
Raw Normal View History

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<FocusAssistChangedDetail>('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]);
}