Merge pull request #1432 from suryo12/refactor/1358-jotai-slideout-tick

refactor(web): replace slideout panel window event with jotai atom (f…
This commit is contained in:
Rohan Verma 2026-05-24 18:50:17 -07:00 committed by GitHub
commit ba18d932e6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 28 additions and 13 deletions

View file

@ -105,7 +105,7 @@ import { useMediaQuery } from "@/hooks/use-media-query";
import { useElectronAPI } from "@/hooks/use-platform";
import { captureDisplayToPngDataUrl } from "@/lib/chat/display-media-capture";
import { getMentionDocKey } from "@/lib/chat/mention-doc-key";
import { SLIDEOUT_PANEL_OPENED_EVENT } from "@/lib/layout-events";
import { slideoutOpenedTickAtom } from "@/lib/layout-events";
import { cn } from "@/lib/utils";
const COMPOSER_PLACEHOLDER = "Ask anything, type / for prompts, type @ to mention docs";
@ -478,15 +478,18 @@ const Composer: FC = () => {
editorRef.current?.focus();
}, [isDesktop, showDocumentPopover, showPromptPicker, threadId]);
// Close document picker when a slide-out panel (inbox, etc.) opens.
// Close document picker when a sidebar slide-out panel (inbox, etc.) opens.
// React only on changes to the tick — comparing against the previously-seen
// value preserves the one-shot semantics of the prior window-event approach
// (no retroactive close on mount if a panel had already opened earlier).
const slideoutOpenedTick = useAtomValue(slideoutOpenedTickAtom);
const lastSeenSlideoutTickRef = useRef(slideoutOpenedTick);
useEffect(() => {
const handler = () => {
setShowDocumentPopover(false);
setMentionQuery("");
};
window.addEventListener(SLIDEOUT_PANEL_OPENED_EVENT, handler);
return () => window.removeEventListener(SLIDEOUT_PANEL_OPENED_EVENT, handler);
}, []);
if (lastSeenSlideoutTickRef.current === slideoutOpenedTick) return;
lastSeenSlideoutTickRef.current = slideoutOpenedTick;
setShowDocumentPopover(false);
setMentionQuery("");
}, [slideoutOpenedTick]);
// Sync editor text into assistant-ui's composer and mirror the chip
// atom from the editor's reported ``docs``. The editor is the

View file

@ -1,9 +1,10 @@
"use client";
import { useSetAtom } from "jotai";
import { AnimatePresence, motion } from "motion/react";
import { useCallback, useEffect } from "react";
import { useIsMobile } from "@/hooks/use-mobile";
import { SLIDEOUT_PANEL_OPENED_EVENT } from "@/lib/layout-events";
import { slideoutOpenedTickAtom } from "@/lib/layout-events";
interface SidebarSlideOutPanelProps {
open: boolean;
@ -29,12 +30,13 @@ export function SidebarSlideOutPanel({
children,
}: SidebarSlideOutPanelProps) {
const isMobile = useIsMobile();
const bumpSlideoutOpenedTick = useSetAtom(slideoutOpenedTickAtom);
useEffect(() => {
if (open) {
window.dispatchEvent(new Event(SLIDEOUT_PANEL_OPENED_EVENT));
bumpSlideoutOpenedTick((tick) => tick + 1);
}
}, [open]);
}, [open, bumpSlideoutOpenedTick]);
const handleEscape = useCallback(
(e: KeyboardEvent) => {