diff --git a/src/app/edit/layout.tsx b/src/app/edit/layout.tsx index c4ab960..9817fbf 100644 --- a/src/app/edit/layout.tsx +++ b/src/app/edit/layout.tsx @@ -94,16 +94,17 @@ const Page: React.FC<{ children: React.ReactNode }> = ({ children }) => { const willChangeEditor = editor; const willChangeEditorId = over.id; - const mathModel = models.filter((model) => model.filename === file.filename); + const mathModel = models.filter((model) => model.id === file.id); if (mathModel.length > 0) { mathModel[0].model && setActiveModel(mathModel[0].filename, mathModel[0].model, willChangeEditorId); mathModel[0].model && setModels( - { filename: mathModel[0].filename, value: '', language: 'typescript' }, + { filename: mathModel[0].filename, value: '', language: 'typescript', id: file.id }, mathModel[0].model, willChangeEditorId, + file.id, ); willChangeEditor?.setModel(mathModel[0].model); } else { diff --git a/src/components/edit/tabItem/index.tsx b/src/components/edit/tabItem/index.tsx index 0355b9d..74b7ed3 100644 --- a/src/components/edit/tabItem/index.tsx +++ b/src/components/edit/tabItem/index.tsx @@ -57,7 +57,7 @@ const Tab: React.FC = ({ const handleTabClick = (e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); - setActiveModel(filename, model, editorId); + setActiveModel(id, model, editorId); editor && editor.setModel(model); }; @@ -65,10 +65,10 @@ const Tab: React.FC = ({ e.preventDefault(); e.stopPropagation(); - const newModels = removeModel(filename, editorId); + const newModels = removeModel(id, editorId); - if (newModels && newModels.filename) { - setActiveModel(newModels.filename, newModels.model, editorId); + if (newModels && newModels.id) { + setActiveModel(newModels.id, newModels.model, editorId); editor && editor.setModel(newModels.model); } else { removeAllModel(editorId); diff --git a/src/components/edit/tabbar/index.tsx b/src/components/edit/tabbar/index.tsx index 9e9a257..af16033 100644 --- a/src/components/edit/tabbar/index.tsx +++ b/src/components/edit/tabbar/index.tsx @@ -57,7 +57,7 @@ export const TabBar: React.FC = ({ editorId }) => { useEffect(() => { setMockModelsForSort( models.map((item) => { - return { ...item, id: item.filename }; + return { ...item }; }), ); }, [models]); @@ -68,9 +68,9 @@ export const TabBar: React.FC = ({ editorId }) => { return ( void, + setModels: ( + modelInfo: modelInfoType, + model: editor.ITextModel, + editorId: number, + id: string, + ) => void, setActiveModel: (modelId: string, model: editor.ITextModel, editorId: number) => void, editorId: number, ) { @@ -19,16 +24,21 @@ export function addNewModel( modelInfo: modelInfoType, monaco: typeof monacoForType, editor: editor.IStandaloneCodeEditor, - setModels: (modelInfo: modelInfoType, model: editor.ITextModel, editorId: number) => void, + setModels: ( + modelInfo: modelInfoType, + model: editor.ITextModel, + editorId: number, + id: string, + ) => void, setActiveModel: (modelId: string, model: editor.ITextModel, editorId: number) => void, editorId: number, ) { - const modelUri = monaco.Uri.file(modelInfo.filename); + const modelUri = monaco.Uri.file(modelInfo.id); const model = monaco.editor.getModel(modelUri) || monaco.editor.createModel(modelInfo.value, modelInfo.language, modelUri); // console.log(monaco.editor.getModel(modelUri)); - setActiveModel(modelInfo.filename, model, editorId); - setModels(modelInfo, model, editorId); + setActiveModel(modelInfo.id, model, editorId); + setModels(modelInfo, model, editorId, modelInfo.id); editor.setModel(model); } diff --git a/src/components/file/fileItem/index.tsx b/src/components/file/fileItem/index.tsx index 7e98519..f204f6c 100644 --- a/src/components/file/fileItem/index.tsx +++ b/src/components/file/fileItem/index.tsx @@ -21,12 +21,13 @@ interface FileItemProps { export const FileItem: React.FC = ({ file, onMouseupFn }: FileItemProps) => { // used for editor - const { splitState } = useSplitStore(); - const { editors } = useEditorStore(); + const { splitState, removeSplit } = useSplitStore(); + const { editors, removeEditor } = useEditorStore(); const { activeEditor, activeEditorId } = useActiveEditorStore(); const { monacos } = useMonacoStore(); const { setActiveModel } = useActiveModelStore(); - const { models, setModels } = useModelsStore(); + const { models, setModels, removeModel, removeAllModel } = useModelsStore(); + const keepedEditorCount = splitState.filter((item) => item).length; // used for dnd const clickClient = useRef({ x: 0, @@ -69,17 +70,17 @@ export const FileItem: React.FC = ({ file, onMouseupFn }: FileIte const willChangeEditorId = activeEditor ? activeEditorId : splitState.findIndex((item) => item); - const mathModel = models.filter((model) => model.filename === file.filename); + const mathModel = models.filter((model) => model.id === file.id); // console.log(splitState, mathModel[0], willChangeEditor, willChangeEditorId); if (mathModel.length > 0) { - mathModel[0].model && - setActiveModel(mathModel[0].filename, mathModel[0].model, willChangeEditorId); + mathModel[0].model && setActiveModel(mathModel[0].id, mathModel[0].model, willChangeEditorId); mathModel[0].model && setModels( - { filename: mathModel[0].filename, value: '', language: 'typescript' }, + { filename: mathModel[0].filename, value: '', language: 'typescript', id: file.id }, mathModel[0].model, willChangeEditorId, + file.id, ); willChangeEditor?.setModel(mathModel[0].model); } else { @@ -120,6 +121,23 @@ export const FileItem: React.FC = ({ file, onMouseupFn }: FileIte onMouseUp={(e) => { e.stopPropagation(); removeFileById(file.id); + + editors.forEach((editor, editorId) => { + const newModels = removeModel(file.id, editorId); + + if (newModels && newModels.filename) { + setActiveModel(newModels.filename, newModels.model, editorId); + editor && editor.setModel(newModels.model); + } else { + removeAllModel(editorId); + editor && editor.setModel(null); + + if (keepedEditorCount > 1) { + removeEditor(editorId); + removeSplit(editorId); + } + } + }); }} className=" w-[15px] pr-[-4px] h-[15px] text-white/70 hover:text-white hidden group-hover:block" /> diff --git a/src/store/editorStore.tsx b/src/store/editorStore.tsx index 614f447..028a446 100644 --- a/src/store/editorStore.tsx +++ b/src/store/editorStore.tsx @@ -67,11 +67,12 @@ export const useMonacoStore = create((set, get) => ( return get().monacos[index] || null; }, })); - +// filename 为model对应文件名,id为uuid export type modelInfoType = { filename: string; language: string; value: string; + id: string; }; export type modelType = modelInfoType & { model: editor.ITextModel; usedBy: number[] }; @@ -81,8 +82,13 @@ interface ModelsState { models: modelsType | []; } interface ModelsAction { - setModels: (modelInfo: modelInfoType, model: editor.ITextModel, editorId: number) => void; - removeModel: (filename: string, editorId: number) => any; + setModels: ( + modelInfo: modelInfoType, + model: editor.ITextModel, + editorId: number, + id: string, + ) => void; + removeModel: (id: string, editorId: number) => any; removeAllModel: (editorId: number) => void; } export const useModelsStore = create((set, get) => ({ @@ -96,7 +102,7 @@ export const useModelsStore = create((set, get) => ( } set((state) => { - const existingModelIndex = state.models.findIndex((m) => m.filename === modelInfo.filename); + const existingModelIndex = state.models.findIndex((m) => m.id === modelInfo.id); if (existingModelIndex === -1) { return { @@ -124,21 +130,21 @@ export const useModelsStore = create((set, get) => ( }); }, - removeModel: (filename: string, editorId: number) => { + removeModel: (id: string, editorId: number) => { set((state) => { - const existingModelIndex = state.models.findIndex((m) => m.filename === filename); + const existingModelIndex = state.models.findIndex((m) => m.id === id); if (existingModelIndex !== -1) { const preModels = [...state.models]; if (preModels[existingModelIndex].usedBy.includes(editorId)) { preModels[existingModelIndex].usedBy = preModels[existingModelIndex].usedBy.filter( - (id) => id !== editorId, + (eid) => eid !== editorId, ); if (preModels[existingModelIndex].usedBy.length === 0) { return { - models: [...preModels.filter((model) => model.filename !== filename)], + models: [...preModels.filter((model) => model.id !== id)], }; } else { return { @@ -183,6 +189,7 @@ export const useModelsStore = create((set, get) => ( }, })); +// modelId原为model对应文件名,为满足打开多个同名文件修改为对应文件的uuid interface activeModelState { activeMap: { modelId: string; model: editor.ITextModel | null }[]; } @@ -194,7 +201,6 @@ interface activeModelAction { export const useActiveModelStore = create((set) => ({ activeMap: [], - setActiveModel: (modelId: string, model: editor.ITextModel, editorId: number) => set((state) => { const preActiveMap = [...state.activeMap];