diff --git a/apps/web/src/components/ChatComposer.tsx b/apps/web/src/components/ChatComposer.tsx index 4401ea0a9..805514337 100644 --- a/apps/web/src/components/ChatComposer.tsx +++ b/apps/web/src/components/ChatComposer.tsx @@ -283,9 +283,6 @@ export const ChatComposer = forwardRef( const toolsMenuRef = useRef(null); const toolsTriggerRef = useRef(null); const petEnabled = Boolean(onAdoptPet && onTogglePet); - const [petMenuOpen, setPetMenuOpen] = useState(false); - const petWrapRef = useRef(null); - const [petMenuStyle, setPetMenuStyle] = useState({}); const linkedDirs = projectMetadata?.linkedDirs ?? []; // initialDraft is only honored on the first non-empty value the parent // hands us. After we seed once, the composer is fully under user control @@ -329,52 +326,6 @@ export const ChatComposer = forwardRef( }; }, [toolsOpen]); - useEffect(() => { - if (!petMenuOpen) return; - function onPointer(e: MouseEvent) { - const target = e.target as Node; - if (petWrapRef.current?.contains(target)) return; - setPetMenuOpen(false); - } - function onKey(e: KeyboardEvent) { - if (e.key === 'Escape') setPetMenuOpen(false); - } - document.addEventListener('mousedown', onPointer); - document.addEventListener('keydown', onKey); - return () => { - document.removeEventListener('mousedown', onPointer); - document.removeEventListener('keydown', onKey); - }; - }, [petMenuOpen]); - - // Viewport-aware pet menu positioning — flips the popover to stay - // within screen bounds instead of clipping at the edge. - useEffect(() => { - if (!petMenuOpen) return; - const wrap = petWrapRef.current; - if (!wrap) return; - const rect = wrap.getBoundingClientRect(); - const menuW = 260; - const menuH = 200; - const gap = 6; - const viewW = window.innerWidth; - const viewH = window.innerHeight; - // Prefer opening upward (bottom of menu above the button). - // Flip downward when there isn't enough room above. - // When neither direction fits, clamp to viewport bounds. - let top: number; - if (rect.top >= menuH + gap) { - top = rect.top - menuH - gap; - } else if (rect.bottom + menuH + gap <= viewH) { - top = rect.bottom + gap; - } else { - top = Math.max(gap, viewH - menuH - gap); - } - // Right-align by default (menu right edge ≈ button right edge). - // Shift left when the menu would spill past the viewport left edge. - const left = Math.max(8, Math.min(viewW - menuW - 8, rect.right - menuW)); - setPetMenuStyle({ position: 'fixed', top, left }); - }, [petMenuOpen]); // Lazy-fetch the user's external MCP servers list once on mount so the // `/mcp …` slash palette and the composer's MCP button popover have @@ -1756,70 +1707,6 @@ export const ChatComposer = forwardRef( ) : null} - {petEnabled ? ( -
- - {petMenuOpen ? ( -
-
- {t('pet.composerMenuTitle')} - {t('pet.composerMenuHint')} -
- - -
- ) : null} -
- ) : null}