diff --git a/src/workspaces/officerdev/src/components/Workspace/WorkspaceView.tsx b/src/workspaces/officerdev/src/components/Workspace/WorkspaceView.tsx index e9cbccb2..f0fd3b3f 100644 --- a/src/workspaces/officerdev/src/components/Workspace/WorkspaceView.tsx +++ b/src/workspaces/officerdev/src/components/Workspace/WorkspaceView.tsx @@ -1,4 +1,4 @@ -import { useState, useCallback, useEffect } from 'react'; +import { useState, useCallback, useEffect, useRef, type ComponentRef } from 'react'; import { flushSync } from 'react-dom'; import { ResizablePanel, ResizablePanelGroup, ResizableHandle } from '@/components/ui/resizable'; import type { LayoutNode, WorkspaceState, EphemeralPanels, PanelComponents } from './types'; @@ -111,43 +111,22 @@ export const WorkspaceView = ({ workspace, cwd = '~', root, initialFilePath, def return () => window.removeEventListener('keydown', onKeyDown); }, [swapSourceId, dragSourceId, maximizedPanelId, setMaximizedAnimated]); + const ephemeralPanelRef = useRef>(null); + const isEphemeralOpen = !!ephemeral; + + useEffect(() => { + const panel = ephemeralPanelRef.current; + if (!panel) return; + + if (isEphemeralOpen) { + panel.resize(100 - (ephemeral.defaultBaseSize ?? 40)); + } else { + panel.collapse(); + } + }, [isEphemeralOpen, ephemeral?.defaultBaseSize]); + if (!workspace.isLoaded) return null; - const baseRenderer = ( - - ); - - const content = ephemeral ? ( - - - {baseRenderer} - - - - - - - ) : ( - baseRenderer - ); - return ( - {content} + + + + + + + {isEphemeralOpen ? ( + + ) : null} + + ); }; diff --git a/src/workspaces/officerdev/src/hooks/useFileViewerPanels/useFileViewerPanels.tsx b/src/workspaces/officerdev/src/hooks/useFileViewerPanels/useFileViewerPanels.tsx index f7f8e2e8..d71b5738 100644 --- a/src/workspaces/officerdev/src/hooks/useFileViewerPanels/useFileViewerPanels.tsx +++ b/src/workspaces/officerdev/src/hooks/useFileViewerPanels/useFileViewerPanels.tsx @@ -1,3 +1,4 @@ +import { useCallback, useMemo } from 'react'; import { useSearchParams } from 'react-router'; import type { EphemeralPanels } from '../../components/Workspace'; import { FileViewerHeader, FileViewerBody } from '../../apps/FileViewer'; @@ -17,42 +18,57 @@ export const useFileViewerPanels = (): EphemeralPanels | null => { ? viewerWithEphemeralLayout : singleViewerLayout; - const components = { - 'files-viewer': { - provider: ViewerProvider, - header: FileViewerHeader, - component: FileViewerBody, - onClose: () => setSearchParams({}), - }, - 'files-ephemeral': { - provider: EphemeralProvider, - header: FileViewerHeader, - component: FileViewerBody, - onClose: () => - setSearchParams((prev) => { - const next = new URLSearchParams(prev); - next.delete('ephemeral'); - next.delete('ephemeralRoot'); - next.delete('ephemeral2'); - next.delete('ephemeral2Root'); - next.delete('ephemeral2Auto'); - return next; - }), - }, - 'files-ephemeral2': { - provider: Ephemeral2Provider, - header: FileViewerHeader, - component: FileViewerBody, - onClose: () => - setSearchParams((prev) => { - const next = new URLSearchParams(prev); - next.delete('ephemeral2'); - next.delete('ephemeral2Root'); - next.delete('ephemeral2Auto'); - return next; - }), - }, - }; + const onCloseViewer = useCallback(() => setSearchParams({}), [setSearchParams]); + + const onCloseEphemeral = useCallback( + () => + setSearchParams((prev) => { + const next = new URLSearchParams(prev); + next.delete('ephemeral'); + next.delete('ephemeralRoot'); + next.delete('ephemeral2'); + next.delete('ephemeral2Root'); + next.delete('ephemeral2Auto'); + return next; + }), + [setSearchParams], + ); + + const onCloseEphemeral2 = useCallback( + () => + setSearchParams((prev) => { + const next = new URLSearchParams(prev); + next.delete('ephemeral2'); + next.delete('ephemeral2Root'); + next.delete('ephemeral2Auto'); + return next; + }), + [setSearchParams], + ); + + const components = useMemo( + () => ({ + 'files-viewer': { + provider: ViewerProvider, + header: FileViewerHeader, + component: FileViewerBody, + onClose: onCloseViewer, + }, + 'files-ephemeral': { + provider: EphemeralProvider, + header: FileViewerHeader, + component: FileViewerBody, + onClose: onCloseEphemeral, + }, + 'files-ephemeral2': { + provider: Ephemeral2Provider, + header: FileViewerHeader, + component: FileViewerBody, + onClose: onCloseEphemeral2, + }, + }), + [onCloseViewer, onCloseEphemeral, onCloseEphemeral2], + ); if (!viewPath) return null; return { layout, components, defaultBaseSize: 40 };