import React, { useCallback, useEffect, useState } from 'react'; import ChatInterface from '../../chat/view/ChatInterface'; import FileTree from '../../file-tree/view/FileTree'; import StandaloneShell from '../../standalone-shell/view/StandaloneShell'; import GitPanel from '../../git-panel/view/GitPanel'; import PluginTabContent from '../../plugins/view/PluginTabContent'; import { BrowserUsePanel } from '../../browser-use'; import type { MainContentProps } from '../types/types'; import { useTaskMaster } from '../../../contexts/TaskMasterContext'; import { usePaletteOpsRegister } from '../../../contexts/PaletteOpsContext'; import { useTasksSettings } from '../../../contexts/TasksSettingsContext'; import { useUiPreferences } from '../../../hooks/useUiPreferences'; import { authenticatedFetch } from '../../../utils/api'; import { useEditorSidebar } from '../../code-editor/hooks/useEditorSidebar'; import EditorSidebar from '../../code-editor/view/EditorSidebar'; import type { Project } from '../../../types/app'; import { TaskMasterPanel } from '../../task-master'; import MainContentHeader from './subcomponents/MainContentHeader'; import MainContentStateView from './subcomponents/MainContentStateView'; import ErrorBoundary from './ErrorBoundary'; type TaskMasterContextValue = { currentProject?: Project | null; setCurrentProject?: ((project: Project) => void) | null; }; type TasksSettingsContextValue = { tasksEnabled: boolean; isTaskMasterInstalled: boolean | null; isTaskMasterReady: boolean | null; }; function MainContent({ selectedProject, selectedSession, activeTab, setActiveTab, ws, sendMessage, isMobile, onMenuClick, isLoading, onInputFocusChange, onSessionProcessing, onSessionIdle, processingSessions, onNavigateToSession, onSessionEstablished, onShowSettings, externalMessageUpdate, newSessionTrigger, }: MainContentProps) { const { preferences } = useUiPreferences(); const { autoExpandTools, showRawParameters, showThinking, autoScrollToBottom, sendByCtrlEnter } = preferences; const { currentProject, setCurrentProject } = useTaskMaster() as TaskMasterContextValue; const { tasksEnabled, isTaskMasterInstalled } = useTasksSettings() as TasksSettingsContextValue; const [browserUseEnabled, setBrowserUseEnabled] = useState(false); const shouldShowTasksTab = Boolean(tasksEnabled && isTaskMasterInstalled); const shouldShowBrowserTab = browserUseEnabled; const { editingFile, editorWidth, editorExpanded, hasManualWidth, resizeHandleRef, handleFileOpen, handleCloseEditor, handleToggleEditorExpand, handleResizeStart, } = useEditorSidebar({ selectedProject, isMobile, }); useEffect(() => { // Identify projects by DB `projectId`; the TaskMaster context uses the // same identifier to key its internal maps. const selectedProjectId = selectedProject?.projectId; const currentProjectId = currentProject?.projectId; if (selectedProject && selectedProjectId !== currentProjectId) { setCurrentProject?.(selectedProject); } }, [selectedProject, currentProject?.projectId, setCurrentProject]); useEffect(() => { if (!shouldShowTasksTab && activeTab === 'tasks') { setActiveTab('chat'); } }, [shouldShowTasksTab, activeTab, setActiveTab]); const loadBrowserUseSettings = useCallback(async () => { try { const response = await authenticatedFetch('/api/browser-use/settings'); const data = await response.json(); setBrowserUseEnabled(Boolean(response.ok && data?.success !== false && data?.data?.settings?.enabled)); } catch { setBrowserUseEnabled(false); } }, []); useEffect(() => { void loadBrowserUseSettings(); window.addEventListener('browserUseSettingsChanged', loadBrowserUseSettings); return () => window.removeEventListener('browserUseSettingsChanged', loadBrowserUseSettings); }, [loadBrowserUseSettings]); useEffect(() => { if (!shouldShowBrowserTab && activeTab === 'browser') { setActiveTab('chat'); } }, [shouldShowBrowserTab, activeTab, setActiveTab]); usePaletteOpsRegister({ openFile: (filePath: string) => { setActiveTab('files'); handleFileOpen(filePath); }, }); if (isLoading) { return ; } if (!selectedProject) { return ; } return (
setActiveTab('tasks') : null} />
{activeTab === 'files' && (
)} {activeTab === 'shell' && (
)} {activeTab === 'git' && (
)} {shouldShowTasksTab && } {shouldShowBrowserTab && activeTab === 'browser' && (
)} {activeTab.startsWith('plugin:') && (
)}
); } export default React.memo(MainContent);