| 1 | // Transient overlays are independent of application page navigation. |
| 2 | import type { Dispatch, SetStateAction } from "react"; |
| 3 | import { create } from "zustand"; |
| 4 | |
| 5 | import { shouldShowStartupSplash } from "../lib/startupSplashState"; |
| 6 | import type { ExtensionActionView, SessionMeta } from "../lib/types"; |
| 7 | |
| 8 | import { applySetState } from "./setState"; |
| 9 | |
| 10 | export type OverlayState = { |
| 11 | paletteOpen: boolean; |
| 12 | paletteSessions: SessionMeta[]; |
| 13 | // Extension actions snapshotted when the palette opens (same staleness |
| 14 | // contract as paletteSessions). |
| 15 | paletteExtensionActions: ExtensionActionView[]; |
| 16 | shortcutsOpen: boolean; |
| 17 | topicExportOpen: boolean; |
| 18 | sidebarSearchOpen: boolean; |
| 19 | sidebarSearchFocusSignal: number; |
| 20 | transientOverlayDismissSignal: number; |
| 21 | startupSplashVisible: boolean; |
| 22 | needsOnboarding: boolean | null; |
| 23 | takeoverDialogTab: string | null; |
| 24 | reclaimBusyTab: string | null; |
| 25 | providerSetupNeeded: boolean; |
| 26 | setPaletteOpen: Dispatch<SetStateAction<boolean>>; |
| 27 | setPaletteSessions: Dispatch<SetStateAction<SessionMeta[]>>; |
| 28 | setPaletteExtensionActions: Dispatch<SetStateAction<ExtensionActionView[]>>; |
| 29 | setShortcutsOpen: Dispatch<SetStateAction<boolean>>; |
| 30 | setTopicExportOpen: Dispatch<SetStateAction<boolean>>; |
| 31 | setSidebarSearchOpen: Dispatch<SetStateAction<boolean>>; |
| 32 | setSidebarSearchFocusSignal: Dispatch<SetStateAction<number>>; |
| 33 | setTransientOverlayDismissSignal: Dispatch<SetStateAction<number>>; |
| 34 | setStartupSplashVisible: Dispatch<SetStateAction<boolean>>; |
| 35 | setNeedsOnboarding: Dispatch<SetStateAction<boolean | null>>; |
| 36 | setTakeoverDialogTab: Dispatch<SetStateAction<string | null>>; |
| 37 | setReclaimBusyTab: Dispatch<SetStateAction<string | null>>; |
| 38 | setProviderSetupNeeded: Dispatch<SetStateAction<boolean>>; |
| 39 | }; |
| 40 | |
| 41 | export const useOverlayStore = create<OverlayState>((set) => ({ |
| 42 | paletteOpen: false, |
| 43 | paletteSessions: [], |
| 44 | paletteExtensionActions: [], |
| 45 | shortcutsOpen: false, |
| 46 | topicExportOpen: false, |
| 47 | sidebarSearchOpen: false, |
| 48 | sidebarSearchFocusSignal: 0, |
| 49 | transientOverlayDismissSignal: 0, |
| 50 | startupSplashVisible: shouldShowStartupSplash(), |
| 51 | needsOnboarding: null, |
| 52 | takeoverDialogTab: null, |
| 53 | reclaimBusyTab: null, |
| 54 | providerSetupNeeded: false, |
| 55 | setPaletteOpen: (update) => set((s) => ({ paletteOpen: applySetState(s.paletteOpen, update) })), |
| 56 | setPaletteSessions: (update) => set((s) => ({ paletteSessions: applySetState(s.paletteSessions, update) })), |
| 57 | setPaletteExtensionActions: (update) => set((s) => ({ paletteExtensionActions: applySetState(s.paletteExtensionActions, update) })), |
| 58 | setShortcutsOpen: (update) => set((s) => ({ shortcutsOpen: applySetState(s.shortcutsOpen, update) })), |
| 59 | setTopicExportOpen: (update) => set((s) => ({ topicExportOpen: applySetState(s.topicExportOpen, update) })), |
| 60 | setSidebarSearchOpen: (update) => set((s) => ({ sidebarSearchOpen: applySetState(s.sidebarSearchOpen, update) })), |
| 61 | setSidebarSearchFocusSignal: (update) => set((s) => ({ sidebarSearchFocusSignal: applySetState(s.sidebarSearchFocusSignal, update) })), |
| 62 | setTransientOverlayDismissSignal: (update) => set((s) => ({ transientOverlayDismissSignal: applySetState(s.transientOverlayDismissSignal, update) })), |
| 63 | setStartupSplashVisible: (update) => set((s) => ({ startupSplashVisible: applySetState(s.startupSplashVisible, update) })), |
| 64 | setNeedsOnboarding: (update) => set((s) => ({ needsOnboarding: applySetState(s.needsOnboarding, update) })), |
| 65 | setTakeoverDialogTab: (update) => set((s) => ({ takeoverDialogTab: applySetState(s.takeoverDialogTab, update) })), |
| 66 | setReclaimBusyTab: (update) => set((s) => ({ reclaimBusyTab: applySetState(s.reclaimBusyTab, update) })), |
| 67 | setProviderSetupNeeded: (update) => set((s) => ({ providerSetupNeeded: applySetState(s.providerSetupNeeded, update) })), |
| 68 | })); |
| 69 |