Files
claudecodeui/src/components/main-content/view/MainContent.tsx
2026-03-05 22:51:27 +00:00

193 lines
6.6 KiB
TypeScript

import React, { useEffect } 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 ErrorBoundary from '../../ErrorBoundary';
import MainContentHeader from './subcomponents/MainContentHeader';
import MainContentStateView from './subcomponents/MainContentStateView';
import TaskMasterPanel from './subcomponents/TaskMasterPanel';
import PluginTabContent from '../../plugins/PluginTabContent';
import type { MainContentProps } from '../types/types';
import { useTaskMaster } from '../../../contexts/TaskMasterContext';
import { useTasksSettings } from '../../../contexts/TasksSettingsContext';
import { useUiPreferences } from '../../../hooks/useUiPreferences';
import { useEditorSidebar } from '../../code-editor/hooks/useEditorSidebar';
import EditorSidebar from '../../code-editor/view/EditorSidebar';
import type { Project } from '../../../types/app';
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,
latestMessage,
isMobile,
onMenuClick,
isLoading,
onInputFocusChange,
onSessionActive,
onSessionInactive,
onSessionProcessing,
onSessionNotProcessing,
processingSessions,
onReplaceTemporarySession,
onNavigateToSession,
onShowSettings,
externalMessageUpdate,
}: MainContentProps) {
const { preferences } = useUiPreferences();
const { autoExpandTools, showRawParameters, showThinking, autoScrollToBottom, sendByCtrlEnter } = preferences;
const { currentProject, setCurrentProject } = useTaskMaster() as TaskMasterContextValue;
const { tasksEnabled, isTaskMasterInstalled } = useTasksSettings() as TasksSettingsContextValue;
const shouldShowTasksTab = Boolean(tasksEnabled && isTaskMasterInstalled);
const {
editingFile,
editorWidth,
editorExpanded,
hasManualWidth,
resizeHandleRef,
handleFileOpen,
handleCloseEditor,
handleToggleEditorExpand,
handleResizeStart,
} = useEditorSidebar({
selectedProject,
isMobile,
});
useEffect(() => {
if (selectedProject && selectedProject !== currentProject) {
setCurrentProject?.(selectedProject);
}
}, [selectedProject, currentProject, setCurrentProject]);
useEffect(() => {
if (!shouldShowTasksTab && activeTab === 'tasks') {
setActiveTab('chat');
}
}, [shouldShowTasksTab, activeTab, setActiveTab]);
if (isLoading) {
return <MainContentStateView mode="loading" isMobile={isMobile} onMenuClick={onMenuClick} />;
}
if (!selectedProject) {
return <MainContentStateView mode="empty" isMobile={isMobile} onMenuClick={onMenuClick} />;
}
return (
<div className="h-full flex flex-col">
<MainContentHeader
activeTab={activeTab}
setActiveTab={setActiveTab}
selectedProject={selectedProject}
selectedSession={selectedSession}
shouldShowTasksTab={shouldShowTasksTab}
isMobile={isMobile}
onMenuClick={onMenuClick}
/>
<div className="flex-1 flex min-h-0 overflow-hidden">
<div className={`flex flex-col min-h-0 min-w-[200px] overflow-hidden ${editorExpanded ? 'hidden' : ''} flex-1`}>
<div className={`h-full ${activeTab === 'chat' ? 'block' : 'hidden'}`}>
<ErrorBoundary showDetails>
<ChatInterface
selectedProject={selectedProject}
selectedSession={selectedSession}
ws={ws}
sendMessage={sendMessage}
latestMessage={latestMessage}
onFileOpen={handleFileOpen}
onInputFocusChange={onInputFocusChange}
onSessionActive={onSessionActive}
onSessionInactive={onSessionInactive}
onSessionProcessing={onSessionProcessing}
onSessionNotProcessing={onSessionNotProcessing}
processingSessions={processingSessions}
onReplaceTemporarySession={onReplaceTemporarySession}
onNavigateToSession={onNavigateToSession}
onShowSettings={onShowSettings}
autoExpandTools={autoExpandTools}
showRawParameters={showRawParameters}
showThinking={showThinking}
autoScrollToBottom={autoScrollToBottom}
sendByCtrlEnter={sendByCtrlEnter}
externalMessageUpdate={externalMessageUpdate}
onShowAllTasks={tasksEnabled ? () => setActiveTab('tasks') : null}
/>
</ErrorBoundary>
</div>
{activeTab === 'files' && (
<div className="h-full overflow-hidden">
<FileTree selectedProject={selectedProject} onFileOpen={handleFileOpen} />
</div>
)}
{activeTab === 'shell' && (
<div className="h-full w-full overflow-hidden">
<StandaloneShell project={selectedProject} session={selectedSession} showHeader={false} />
</div>
)}
{activeTab === 'git' && (
<div className="h-full overflow-hidden">
<GitPanel selectedProject={selectedProject} isMobile={isMobile} onFileOpen={handleFileOpen} />
</div>
)}
{shouldShowTasksTab && <TaskMasterPanel isVisible={activeTab === 'tasks'} />}
<div className={`h-full overflow-hidden ${activeTab === 'preview' ? 'block' : 'hidden'}`} />
{activeTab.startsWith('plugin:') && (
<div className="h-full overflow-hidden">
<PluginTabContent
pluginName={activeTab.replace('plugin:', '')}
selectedProject={selectedProject}
selectedSession={selectedSession}
/>
</div>
)}
</div>
<EditorSidebar
editingFile={editingFile}
isMobile={isMobile}
editorExpanded={editorExpanded}
editorWidth={editorWidth}
hasManualWidth={hasManualWidth}
resizeHandleRef={resizeHandleRef}
onResizeStart={handleResizeStart}
onCloseEditor={handleCloseEditor}
onToggleEditorExpand={handleToggleEditorExpand}
projectPath={selectedProject.path}
fillSpace={activeTab === 'files'}
/>
</div>
</div>
);
}
export default React.memo(MainContent);