import { useCallback, useEffect, useRef, useState } from 'react'; import type { MouseEvent as ReactMouseEvent } from 'react'; import type { Project } from '../../../types/app'; import type { CodeEditorDiffInfo, CodeEditorFile } from '../types/types'; type UseEditorSidebarOptions = { selectedProject: Project | null; isMobile: boolean; initialWidth?: number; }; export const useEditorSidebar = ({ selectedProject, isMobile, initialWidth = 600, }: UseEditorSidebarOptions) => { const [editingFile, setEditingFile] = useState(null); const [editorWidth, setEditorWidth] = useState(initialWidth); const [editorExpanded, setEditorExpanded] = useState(false); const [isResizing, setIsResizing] = useState(false); const [hasManualWidth, setHasManualWidth] = useState(false); const resizeHandleRef = useRef(null); const handleFileOpen = useCallback( (filePath: string, diffInfo: CodeEditorDiffInfo | null = null) => { const normalizedPath = filePath.replace(/\\/g, '/'); const fileName = normalizedPath.split('/').pop() || filePath; setEditingFile({ name: fileName, path: filePath, projectName: selectedProject?.name, diffInfo, }); }, [selectedProject?.name], ); const handleCloseEditor = useCallback(() => { setEditingFile(null); setEditorExpanded(false); }, []); const handleToggleEditorExpand = useCallback(() => { setEditorExpanded((previous) => !previous); }, []); const handleResizeStart = useCallback( (event: ReactMouseEvent) => { if (isMobile) { return; } // After first drag interaction, the editor width is user-controlled. setHasManualWidth(true); setIsResizing(true); event.preventDefault(); }, [isMobile], ); useEffect(() => { const handleMouseMove = (event: globalThis.MouseEvent) => { if (!isResizing) { return; } const container = resizeHandleRef.current?.parentElement; if (!container) { return; } const containerRect = container.getBoundingClientRect(); const newWidth = containerRect.right - event.clientX; const minWidth = 300; const maxWidth = containerRect.width * 0.8; if (newWidth >= minWidth && newWidth <= maxWidth) { setEditorWidth(newWidth); } }; const handleMouseUp = () => { setIsResizing(false); }; if (isResizing) { document.addEventListener('mousemove', handleMouseMove); document.addEventListener('mouseup', handleMouseUp); document.body.style.cursor = 'col-resize'; document.body.style.userSelect = 'none'; } return () => { document.removeEventListener('mousemove', handleMouseMove); document.removeEventListener('mouseup', handleMouseUp); document.body.style.cursor = ''; document.body.style.userSelect = ''; }; }, [isResizing]); return { editingFile, editorWidth, editorExpanded, hasManualWidth, resizeHandleRef, handleFileOpen, handleCloseEditor, handleToggleEditorExpand, handleResizeStart, }; };