Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 60 additions & 19 deletions src/renderer/components/FileExplorer/CodeEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { FileTree } from './FileTree';
import { FileTabs } from './FileTabs';
import { EditorHeader } from './EditorHeader';
import { MarkdownPreview } from './MarkdownPreview';
import { SettingsPage, type SettingsPageTab } from '../SettingsPage';
import '@/styles/editor-diff.css';

interface CodeEditorProps {
Expand All @@ -35,6 +36,9 @@ interface CodeEditorProps {
onClose: () => void;
connectionId?: string | null;
remotePath?: string | null;
showSettingsPage?: boolean;
settingsPageInitialTab?: SettingsPageTab;
onCloseSettingsPage?: () => void;
}

export default function CodeEditor({
Expand All @@ -45,12 +49,37 @@ export default function CodeEditor({
onClose,
connectionId,
remotePath,
showSettingsPage,
settingsPageInitialTab,
onCloseSettingsPage,
}: CodeEditorProps) {
const { effectiveTheme } = useTheme();
const { toggle: toggleRightSidebar, collapsed: rightSidebarCollapsed } = useRightSidebar();
const {
toggle: toggleRightSidebar,
collapsed: rightSidebarCollapsed,
setCollapsed: setRightSidebarCollapsed,
} = useRightSidebar();
const monacoRef = useRef<any>(null);
const editorRef = useRef<any>(null);
const editorRegistrationCleanupRef = useRef<(() => void) | null>(null);
const rightSidebarWasCollapsedRef = useRef<boolean>(false);

// Collapse the right sidebar when settings is shown inside the editor,
// and restore the previous state when settings is closed.
useEffect(() => {
if (showSettingsPage) {
rightSidebarWasCollapsedRef.current = rightSidebarCollapsed;
if (!rightSidebarCollapsed) {
setRightSidebarCollapsed(true);
}
} else {
if (!rightSidebarWasCollapsedRef.current && rightSidebarCollapsed) {
setRightSidebarCollapsed(false);
}
}
// Only react to showSettingsPage toggling, not rightSidebarCollapsed changes
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [showSettingsPage, setRightSidebarCollapsed]);

// File management with custom hook
const {
Expand Down Expand Up @@ -277,6 +306,7 @@ export default function CodeEditor({
onSaveAll={saveAllFiles}
onToggleRightSidebar={toggleRightSidebar}
onClose={onClose}
showSettingsPage={showSettingsPage}
/>

<div className="flex flex-1 overflow-hidden">
Expand All @@ -297,24 +327,35 @@ export default function CodeEditor({
/>

<div className="flex flex-1 flex-col overflow-hidden">
<FileTabs
openFiles={openFiles}
activeFilePath={activeFilePath}
onTabClick={setActiveFile}
onTabClose={handleCloseFile}
previewMode={previewMode}
onTogglePreview={togglePreview}
/>

<EditorContent
activeFile={activeFile}
effectiveTheme={effectiveTheme}
onEditorMount={handleEditorMount}
onEditorChange={handleEditorChange}
isPreviewActive={isPreviewActive}
modelRootPath={modelRootPath}
taskPath={taskPath}
/>
{showSettingsPage ? (
<div className="flex min-h-0 flex-1 overflow-hidden bg-background">
<SettingsPage
initialTab={settingsPageInitialTab}
onClose={onCloseSettingsPage || (() => {})}
/>
</div>
) : (
<>
<FileTabs
openFiles={openFiles}
activeFilePath={activeFilePath}
onTabClick={setActiveFile}
onTabClose={handleCloseFile}
previewMode={previewMode}
onTogglePreview={togglePreview}
/>

<EditorContent
activeFile={activeFile}
effectiveTheme={effectiveTheme}
onEditorMount={handleEditorMount}
onEditorChange={handleEditorChange}
isPreviewActive={isPreviewActive}
modelRootPath={modelRootPath}
taskPath={taskPath}
/>
</>
)}
</div>
</div>
</div>
Expand Down
49 changes: 29 additions & 20 deletions src/renderer/components/FileExplorer/EditorHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ interface EditorHeaderProps {
onSaveAll: () => void;
onToggleRightSidebar: () => void;
onClose: () => void;
showSettingsPage?: boolean;
}

export const EditorHeader: React.FC<EditorHeaderProps> = ({
Expand All @@ -20,17 +21,19 @@ export const EditorHeader: React.FC<EditorHeaderProps> = ({
onSaveAll,
onToggleRightSidebar,
onClose,
showSettingsPage,
}) => {
return (
<div className="flex h-9 items-center justify-between border-b border-border bg-muted/30 px-3">
<TaskInfo taskName={taskName} hasUnsavedChanges={hasUnsavedChanges} />
<TaskInfo taskName={taskName} hasUnsavedChanges={hasUnsavedChanges && !showSettingsPage} />
<EditorControls
hasUnsavedChanges={hasUnsavedChanges}
isSaving={isSaving}
rightSidebarCollapsed={rightSidebarCollapsed}
onSaveAll={onSaveAll}
onToggleRightSidebar={onToggleRightSidebar}
onClose={onClose}
showSettingsPage={showSettingsPage}
/>
</div>
);
Expand All @@ -54,34 +57,40 @@ const EditorControls: React.FC<{
onSaveAll: () => void;
onToggleRightSidebar: () => void;
onClose: () => void;
showSettingsPage?: boolean;
}> = ({
hasUnsavedChanges,
isSaving,
rightSidebarCollapsed,
onSaveAll,
onToggleRightSidebar,
onClose,
showSettingsPage,
}) => (
<div className="flex items-center gap-1">
<Button
variant="ghost"
size="icon"
className="h-7 w-7"
onClick={onSaveAll}
disabled={!hasUnsavedChanges || isSaving}
title="Save All (⌘⇧S)"
>
<Save className="h-3.5 w-3.5" />
</Button>
<Button
variant="ghost"
size="icon"
className="h-7 w-7"
onClick={onToggleRightSidebar}
title={rightSidebarCollapsed ? 'Show Changes' : 'Hide Changes'}
>
<PanelRight className="h-3.5 w-3.5" />
</Button>
{!showSettingsPage && (
<>
<Button
variant="ghost"
size="icon"
className="h-7 w-7"
onClick={onSaveAll}
disabled={!hasUnsavedChanges || isSaving}
title="Save All (⌘⇧S)"
>
<Save className="h-3.5 w-3.5" />
</Button>
<Button
variant="ghost"
size="icon"
className="h-7 w-7"
onClick={onToggleRightSidebar}
title={rightSidebarCollapsed ? 'Show Changes' : 'Hide Changes'}
>
<PanelRight className="h-3.5 w-3.5" />
</Button>
</>
)}
<Button variant="ghost" size="icon" className="h-7 w-7" onClick={onClose} title="Close Editor">
<X className="h-3.5 w-3.5" />
</Button>
Expand Down
24 changes: 15 additions & 9 deletions src/renderer/views/Workspace.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -155,14 +155,6 @@ export function Workspace() {
};
}, []);

// Listen for native menu "Settings" click (main → renderer)
useEffect(() => {
const cleanup = window.electronAPI.onMenuOpenSettings?.(() => {
openSettingsPage();
});
return () => cleanup?.();
}, [openSettingsPage]);

// Listen for native menu Undo/Redo (main → renderer) and keep operations editor-scoped.
useEffect(() => {
const cleanupUndo = window.electronAPI.onMenuUndo?.(() => {
Expand All @@ -189,6 +181,14 @@ export function Workspace() {
const projectMgmt = useProjectManagementContext();
const { showEditorMode, setShowEditorMode, setShowKanban } = projectMgmt;

// Listen for native menu "Settings" click (main → renderer)
useEffect(() => {
const cleanup = window.electronAPI.onMenuOpenSettings?.(() => {
openSettingsPage();
});
return () => cleanup?.();
}, [openSettingsPage]);

const handleToggleKanban = useCallback(() => {
if (!projectMgmt.selectedProject) return;
setShowEditorMode(false);
Expand Down Expand Up @@ -257,7 +257,10 @@ export function Workspace() {
});

// Show toast on update availability
useUpdateNotifier({ checkOnMount: true, onOpenSettings: () => openSettingsPage('general') });
useUpdateNotifier({
checkOnMount: true,
onOpenSettings: () => openSettingsPage('general'),
});

// Listen for native menu "Check for Updates" click (main → renderer)
useEffect(() => {
Expand Down Expand Up @@ -485,6 +488,9 @@ export function Workspace() {
onClose={handleCloseEditor}
connectionId={derivedRemoteConnectionId}
remotePath={derivedRemotePath}
showSettingsPage={showSettingsPage}
settingsPageInitialTab={settingsPageInitialTab}
onCloseSettingsPage={handleCloseSettingsPage}
/>
)}

Expand Down
Loading