import React from 'react'; import { Icon } from '@/components/icon/Icon'; import { useI18n } from '@/lib/i18n'; import { cn } from '@/lib/utils'; import { useDirectoryStore } from '@/stores/useDirectoryStore'; import { useSessionUIStore } from '@/sync/session-ui-store'; import { useSession } from '@/sync/sync-context'; import { MobileSessionMetadataButton } from './MobileSessionMetadata'; import { MobileSessionSwitcher } from './MobileSessionSwitcher'; export const MobileHeader: React.FC<{ onOpenSessions: () => void; /** Opens the right workspace drawer (Changes / Files / Terminal / Notes / MCP). */ onOpenWorkspace: () => void; /** Tablet: size the title trigger to its text instead of the free width, so a wide header doesn't turn the switcher into a full-width tap target. */ compactTitle?: boolean; }> = ({ onOpenSessions, onOpenWorkspace, compactTitle = false }) => { const { t } = useI18n(); const [metadataOpen, setMetadataOpen] = React.useState(false); const [switcherOpen, setSwitcherOpen] = React.useState(false); const titleRef = React.useRef(null); const currentDirectory = useDirectoryStore((state) => state.currentDirectory); const currentSessionId = useSessionUIStore((state) => state.currentSessionId); const currentSessionDirectory = useSessionUIStore( React.useCallback((state) => (currentSessionId ? state.getDirectoryForSession(currentSessionId) : null), [currentSessionId]), ); const effectiveDirectory = currentSessionDirectory || currentDirectory; const currentSession = useSession(currentSessionId, effectiveDirectory || undefined); const isNewSessionDraftOpen = useSessionUIStore((state) => Boolean(state.newSessionDraft?.open)); const sessionTitle = currentSession?.title?.trim(); // Single-line title, desktop-style: session title, or the "New session" // placeholder on the draft screen. No project/branch metadata line. const primaryLabel = sessionTitle || (currentSessionId ? t('mobile.sessions.untitled') : t('sessions.switcher.draftTitle')); React.useEffect(() => { setMetadataOpen(false); setSwitcherOpen(false); }, [currentSessionId, effectiveDirectory]); const handleOpenSessions = React.useCallback(() => { setMetadataOpen(false); setSwitcherOpen(false); onOpenSessions(); }, [onOpenSessions]); // The two header popovers are mutually exclusive. const handleMetadataOpenChange = React.useCallback((value: boolean | ((open: boolean) => boolean)) => { setMetadataOpen((current) => { const next = typeof value === 'function' ? value(current) : value; if (next) setSwitcherOpen(false); return next; }); }, []); const toggleSwitcher = React.useCallback(() => { setSwitcherOpen((current) => { const next = !current; if (next) setMetadataOpen(false); return next; }); }, []); return ( <>
{/* Session title doubles as the recent-sessions switcher trigger. */} {/* Compact title: this takes the leftover width so the trailing controls stay pinned to the right edge. */} {compactTitle ?
: null}
setSwitcherOpen(false)} anchorRef={titleRef} /> ); };