import { useEffect, useSyncExternalStore } from 'react'; /** * Screens whose own buttons sit bottom-right, where the Copilot's reminder * bubble would cover them (Save changes, Save and continue). While one is * mounted the launcher keeps its button and count but shows no bubble. */ let screens = 0; const listeners = new Set<() => void>(); const notify = (): void => listeners.forEach(listener => listener()); const subscribe = (listener: () => void): (() => void) => { listeners.add(listener); return () => listeners.delete(listener); }; const isQuiet = (): boolean => screens > 0; /** * Keeps the launcher's bubble away while the calling screen is mounted. * * @param active - Whether the screen has its buttons on screen now. */ export const useQuietLauncher = (active = true): void => { useEffect(() => { if (!active) { return undefined; } screens += 1; notify(); return () => { screens -= 1; notify(); }; }, [active]); }; /** * @return Whether a mounted screen asked the launcher to keep its bubble away. */ export const useLauncherQuiet = (): boolean => useSyncExternalStore(subscribe, isQuiet, isQuiet);