mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2026-02-17 13:52:14 +01:00
202 lines
6.9 KiB
TypeScript
202 lines
6.9 KiB
TypeScript
import { Box } from '@mantine/core';
|
|
import { useRainbowThemeContext } from '../shared/RainbowThemeProvider';
|
|
import { useToolWorkflow } from '../../contexts/ToolWorkflowContext';
|
|
import { useFileHandler } from '../../hooks/useFileHandler';
|
|
import { useFileState } from '../../contexts/FileContext';
|
|
import { useNavigationState, useNavigationActions } from '../../contexts/NavigationContext';
|
|
import { isBaseWorkbench } from '../../types/workbench';
|
|
import { useViewer } from '../../contexts/ViewerContext';
|
|
import { useAppConfig } from '../../contexts/AppConfigContext';
|
|
import './Workbench.css';
|
|
|
|
import TopControls from '../shared/TopControls';
|
|
import FileEditor from '../fileEditor/FileEditor';
|
|
import PageEditor from '../pageEditor/PageEditor';
|
|
import PageEditorControls from '../pageEditor/PageEditorControls';
|
|
import Viewer from '../viewer/Viewer';
|
|
import LandingPage from '../shared/LandingPage';
|
|
import Footer from '../shared/Footer';
|
|
import DismissAllErrorsButton from '../shared/DismissAllErrorsButton';
|
|
|
|
// No props needed - component uses contexts directly
|
|
export default function Workbench() {
|
|
const { isRainbowMode } = useRainbowThemeContext();
|
|
const { config } = useAppConfig();
|
|
|
|
// Use context-based hooks to eliminate all prop drilling
|
|
const { selectors } = useFileState();
|
|
const { workbench: currentView } = useNavigationState();
|
|
const { actions: navActions } = useNavigationActions();
|
|
const setCurrentView = navActions.setWorkbench;
|
|
const activeFiles = selectors.getFiles();
|
|
const {
|
|
previewFile,
|
|
pageEditorFunctions,
|
|
sidebarsVisible,
|
|
setPreviewFile,
|
|
setPageEditorFunctions,
|
|
setSidebarsVisible,
|
|
customWorkbenchViews,
|
|
} = useToolWorkflow();
|
|
|
|
const { handleToolSelect } = useToolWorkflow();
|
|
|
|
// Get navigation state - this is the source of truth
|
|
const { selectedTool: selectedToolId } = useNavigationState();
|
|
|
|
// Get tool registry from context (instead of direct hook call)
|
|
const { toolRegistry } = useToolWorkflow();
|
|
const selectedTool = selectedToolId ? toolRegistry[selectedToolId] : null;
|
|
const { addFiles } = useFileHandler();
|
|
|
|
// Get active file index from ViewerContext
|
|
const { activeFileIndex, setActiveFileIndex } = useViewer();
|
|
|
|
const handlePreviewClose = () => {
|
|
setPreviewFile(null);
|
|
const previousMode = sessionStorage.getItem('previousMode');
|
|
if (previousMode === 'split') {
|
|
// Use context's handleToolSelect which coordinates tool selection and view changes
|
|
handleToolSelect('split');
|
|
sessionStorage.removeItem('previousMode');
|
|
} else if (previousMode === 'compress') {
|
|
handleToolSelect('compress');
|
|
sessionStorage.removeItem('previousMode');
|
|
} else if (previousMode === 'convert') {
|
|
handleToolSelect('convert');
|
|
sessionStorage.removeItem('previousMode');
|
|
} else {
|
|
setCurrentView('fileEditor');
|
|
}
|
|
};
|
|
|
|
const renderMainContent = () => {
|
|
if (activeFiles.length === 0) {
|
|
return (
|
|
<LandingPage
|
|
/>
|
|
);
|
|
}
|
|
|
|
switch (currentView) {
|
|
case "fileEditor":
|
|
|
|
return (
|
|
<FileEditor
|
|
toolMode={!!selectedToolId}
|
|
supportedExtensions={selectedTool?.supportedFormats || ["pdf"]}
|
|
{...(!selectedToolId && {
|
|
onOpenPageEditor: () => {
|
|
setCurrentView("pageEditor");
|
|
},
|
|
onMergeFiles: (filesToMerge) => {
|
|
addFiles(filesToMerge);
|
|
setCurrentView("viewer");
|
|
}
|
|
})}
|
|
/>
|
|
);
|
|
|
|
case "viewer":
|
|
|
|
return (
|
|
<Viewer
|
|
sidebarsVisible={sidebarsVisible}
|
|
setSidebarsVisible={setSidebarsVisible}
|
|
previewFile={previewFile}
|
|
onClose={handlePreviewClose}
|
|
activeFileIndex={activeFileIndex}
|
|
setActiveFileIndex={setActiveFileIndex}
|
|
/>
|
|
);
|
|
|
|
case "pageEditor":
|
|
|
|
return (
|
|
<>
|
|
<PageEditor
|
|
onFunctionsReady={setPageEditorFunctions}
|
|
/>
|
|
{pageEditorFunctions && (
|
|
<PageEditorControls
|
|
onClosePdf={pageEditorFunctions.closePdf}
|
|
onUndo={pageEditorFunctions.handleUndo}
|
|
onRedo={pageEditorFunctions.handleRedo}
|
|
canUndo={pageEditorFunctions.canUndo}
|
|
canRedo={pageEditorFunctions.canRedo}
|
|
onRotate={pageEditorFunctions.handleRotate}
|
|
onDelete={pageEditorFunctions.handleDelete}
|
|
onSplit={pageEditorFunctions.handleSplit}
|
|
onSplitAll={pageEditorFunctions.handleSplitAll}
|
|
onPageBreak={pageEditorFunctions.handlePageBreak}
|
|
onPageBreakAll={pageEditorFunctions.handlePageBreakAll}
|
|
onExportAll={pageEditorFunctions.onExportAll}
|
|
exportLoading={pageEditorFunctions.exportLoading}
|
|
selectionMode={pageEditorFunctions.selectionMode}
|
|
selectedPageIds={pageEditorFunctions.selectedPageIds}
|
|
displayDocument={pageEditorFunctions.displayDocument}
|
|
splitPositions={pageEditorFunctions.splitPositions}
|
|
totalPages={pageEditorFunctions.totalPages}
|
|
/>
|
|
)}
|
|
</>
|
|
);
|
|
|
|
default:
|
|
if (!isBaseWorkbench(currentView)) {
|
|
const customView = customWorkbenchViews.find((view) => view.workbenchId === currentView && view.data != null);
|
|
|
|
|
|
if (customView) {
|
|
const CustomComponent = customView.component;
|
|
return <CustomComponent data={customView.data} />;
|
|
}
|
|
}
|
|
return <LandingPage />;
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Box
|
|
className="flex-1 h-full min-w-0 relative flex flex-col"
|
|
data-tour="workbench"
|
|
style={
|
|
isRainbowMode
|
|
? {} // No background color in rainbow mode
|
|
: { backgroundColor: 'var(--bg-background)' }
|
|
}
|
|
>
|
|
{/* Top Controls */}
|
|
{activeFiles.length > 0 && (
|
|
<TopControls
|
|
currentView={currentView}
|
|
setCurrentView={setCurrentView}
|
|
customViews={customWorkbenchViews}
|
|
activeFiles={activeFiles.map(f => {
|
|
const stub = selectors.getStirlingFileStub(f.fileId);
|
|
return { fileId: f.fileId, name: f.name, versionNumber: stub?.versionNumber };
|
|
})}
|
|
currentFileIndex={activeFileIndex}
|
|
onFileSelect={setActiveFileIndex}
|
|
/>
|
|
)}
|
|
|
|
{/* Dismiss All Errors Button */}
|
|
<DismissAllErrorsButton />
|
|
|
|
{/* Main content area */}
|
|
<Box
|
|
className="flex-1 min-h-0 relative z-10 workbench-scrollable "
|
|
style={{
|
|
transition: 'opacity 0.15s ease-in-out',
|
|
paddingTop: currentView === 'viewer' ? '0' : (activeFiles.length > 0 ? '3.5rem' : '0'),
|
|
}}
|
|
>
|
|
{renderMainContent()}
|
|
</Box>
|
|
|
|
<Footer analyticsEnabled={config?.enableAnalytics === true} />
|
|
</Box>
|
|
);
|
|
}
|