diff --git a/packages/ui/src/components/layout/Header.tsx b/packages/ui/src/components/layout/Header.tsx index c7000a9d..265f2354 100644 --- a/packages/ui/src/components/layout/Header.tsx +++ b/packages/ui/src/components/layout/Header.tsx @@ -926,18 +926,13 @@ export const Header: React.FC = () => { const deleteSessions = useSessionUIStore((state) => state.deleteSessions); const [isRenamingHeaderSession, setIsRenamingHeaderSession] = React.useState(false); const [isHeaderSessionMenuOpen, setIsHeaderSessionMenuOpen] = React.useState(false); - const pendingHeaderRenameRef = React.useRef(false); + /** Session id whose rename was requested from a tab menu; survives the + activation that a Rename on an inactive tab performs first. */ + const pendingHeaderRenameRef = React.useRef(null); const [headerSessionTitleDraft, setHeaderSessionTitleDraft] = React.useState(''); const [pendingHeaderRetentionAction, setPendingHeaderRetentionAction] = React.useState<{ action: 'archive' | 'delete'; sessionId: string } | null>(null); const headerRenameFormRef = React.useRef(null); - React.useEffect(() => { - pendingHeaderRenameRef.current = false; - setIsHeaderSessionMenuOpen(false); - setIsRenamingHeaderSession(false); - setHeaderSessionTitleDraft(''); - setPendingHeaderRetentionAction(null); - }, [currentSessionId]); const beginHeaderSessionRename = React.useCallback(() => { if (!currentSessionId) return; @@ -945,6 +940,23 @@ export const Header: React.FC = () => { setIsRenamingHeaderSession(true); }, [currentSession?.title, currentSessionId, currentSessionTitle]); + const beginHeaderSessionRenameRef = React.useRef(beginHeaderSessionRename); + beginHeaderSessionRenameRef.current = beginHeaderSessionRename; + + React.useEffect(() => { + setIsHeaderSessionMenuOpen(false); + setPendingHeaderRetentionAction(null); + if (currentSessionId && pendingHeaderRenameRef.current === currentSessionId) { + // Rename on an inactive tab activates it first; the switch itself is + // when the rename can begin (the menu may close before or after it). + pendingHeaderRenameRef.current = null; + beginHeaderSessionRenameRef.current(); + return; + } + setIsRenamingHeaderSession(false); + setHeaderSessionTitleDraft(''); + }, [currentSessionId]); + const saveHeaderSessionRename = React.useCallback(async () => { if (!currentSessionId) return; const title = headerSessionTitleDraft.trim(); @@ -1536,7 +1548,7 @@ export const Header: React.FC = () => { const canMoveToWorktree = isActive && !isVSCode && !isChatContext && currentSession && !currentSession.parentId; return ( <> - { if (!isActive) select(); pendingHeaderRenameRef.current = true; }}> + { if (!isActive) select(); pendingHeaderRenameRef.current = session.id; }}> {t('sessions.sidebar.session.menu.rename')} copySessionIdFor(session.id)}> @@ -1734,8 +1746,8 @@ export const Header: React.FC = () => { open={isHeaderSessionMenuOpen} onOpenChange={setIsHeaderSessionMenuOpen} onOpenChangeComplete={(open) => { - if (!open && pendingHeaderRenameRef.current) { - pendingHeaderRenameRef.current = false; + if (!open && pendingHeaderRenameRef.current && pendingHeaderRenameRef.current === currentSessionId) { + pendingHeaderRenameRef.current = null; beginHeaderSessionRename(); } }} @@ -1746,7 +1758,7 @@ export const Header: React.FC = () => { - { pendingHeaderRenameRef.current = true; }}>{t('sessions.sidebar.session.menu.rename')} + { pendingHeaderRenameRef.current = currentSessionId; }}>{t('sessions.sidebar.session.menu.rename')} currentSessionId && copySessionIdFor(currentSessionId)}>{t('sessions.sidebar.session.menu.copyId')} {currentSession?.shareUrl ? ( @@ -1806,8 +1818,8 @@ export const Header: React.FC = () => { renderMenu={renderSessionTabMenu} suppressActiveTabControls={isRenamingHeaderSession} onMenuOpenChangeComplete={(open) => { - if (!open && pendingHeaderRenameRef.current) { - pendingHeaderRenameRef.current = false; + if (!open && pendingHeaderRenameRef.current && pendingHeaderRenameRef.current === currentSessionId) { + pendingHeaderRenameRef.current = null; beginHeaderSessionRename(); } }} diff --git a/packages/ui/src/components/layout/SessionTabsStrip.tsx b/packages/ui/src/components/layout/SessionTabsStrip.tsx index 45018366..f4bbe964 100644 --- a/packages/ui/src/components/layout/SessionTabsStrip.tsx +++ b/packages/ui/src/components/layout/SessionTabsStrip.tsx @@ -222,10 +222,11 @@ const SessionTabItem: React.FC<{ data-controls-open={overlayVisible ? 'true' : 'false'} className={cn( 'session-tab group/session-tab relative flex h-7 w-full min-w-0 select-none items-center rounded-md px-2', + 'transition-colors duration-75', isActive ? 'bg-interactive-selection' : cn( - 'cursor-pointer text-muted-foreground transition-colors duration-150 hover:bg-interactive-hover hover:text-foreground', + 'cursor-pointer text-muted-foreground hover:bg-interactive-hover hover:text-foreground', overlayVisible && 'bg-interactive-hover text-foreground', ), )}