diff --git a/packages/core/src/models/designer.ts b/packages/core/src/models/designer.ts index e2dc2d7..46c2580 100644 --- a/packages/core/src/models/designer.ts +++ b/packages/core/src/models/designer.ts @@ -249,8 +249,11 @@ export class Designer { } const editor2workspace = () => { - this.workspace.clearFiles(); - this.workspace.addFiles(this.editor.listFileData()); + console.log('>>>', this.editor.isFilesChanged, this.editor._history); + if (this.editor.isFilesChanged) { + this.workspace.clearFiles(); + this.workspace.addFiles(this.editor.listFileData()); + } }; const workspace2editor = () => { this.editor.clear(); diff --git a/packages/core/src/models/editor-state.ts b/packages/core/src/models/editor-state.ts index 3ba031c..05a2fd2 100644 --- a/packages/core/src/models/editor-state.ts +++ b/packages/core/src/models/editor-state.ts @@ -22,12 +22,22 @@ export class EditorState { _activeFile: string; + _history: EditorHistory; + get activeFile() { return this._activeFile; } + /** + * 文件是否存在变更记录 + */ + get isFilesChanged() { + return this._history.size > 1; + } + constructor(options?: EditorStateConfig) { this._activeFile = options?.defaultActiveFile; + this._history = new EditorHistory(); makeObservable(this, { _activeFile: observable, @@ -38,6 +48,7 @@ export class EditorState { clear() { this._files.clear(); + this._history.clear(); } setActiveFile(filename: string) { @@ -73,31 +84,77 @@ export class EditorState { addFile({ filename, ...rest }: AddFilePayload) { this._files.set(filename, rest); - } - addFiles(fileList: AddFilePayload[]) { - fileList.forEach((file) => { - this.addFile(file); + this._history.push({ + message: 'addFile', + data: [ + { + filename, + ...rest, + }, + ], }); } - deleteFile(payload: DeleteFilePayload) { - this._files.delete(payload.filename); + addFiles(fileList: AddFilePayload[]) { + fileList.forEach(({ filename, ...rest }) => { + this._files.set(filename, rest); + }); + + this._history.push({ + message: 'addFiles', + data: [...fileList], + }); + } + + deleteFile({ filename }: DeleteFilePayload) { + const file = this._files.get(filename); + this._files.delete(filename); + + this._history.push({ + message: 'deleteFile', + data: [ + { + filename, + ...file, + }, + ], + }); } deleteFolder(payload: DeleteFilePayload) { + const deleteFiles: AddFilePayload[] = []; const fileNames = Object.keys(this._files); for (const filename of fileNames) { if (filename.startsWith(payload.filename)) { - this.deleteFile({ filename }); + const file = this._files.get(filename); + deleteFiles.push({ + filename, + ...file, + }); + this._files.delete(filename); } } + + this._history.push({ + message: 'deleteFolder', + data: deleteFiles, + }); } - renameFile({ filename, newFilename }: RenameFilePayload) { + _renameFile({ filename, newFilename }: RenameFilePayload) { const fileData = this._files.get(filename); - this.addFile({ ...fileData, filename: newFilename }); - this.deleteFile({ filename }); + this._files.set(newFilename, { ...fileData }); + this._files.delete(filename); + } + + renameFile(payload: RenameFilePayload) { + this._renameFile(payload); + + this._history.push({ + message: 'renameFile', + data: [payload], + }); } renameFolder({ filename: oldFolderName, newFilename: newFolderName }: RenameFilePayload) { @@ -105,14 +162,79 @@ export class EditorState { for (const filename of fileNames) { if (filename.startsWith(oldFolderName)) { const newFilename = filename.replace(oldFolderName, newFolderName); - this.renameFile({ filename, newFilename }); + this._renameFile({ filename, newFilename }); } } + + this._history.push({ + message: 'renameFolder', + data: [ + { + filename: oldFolderName, + newFilename: newFolderName, + }, + ], + }); } updateFile({ filename, code }: UpdateFilePayload) { const fileData = this._files.get(filename); + if (fileData.code === code) { + // 代码未发生变化 + return; + } + fileData.code = code; this._files.set(filename, fileData); + + this._history.push({ + message: 'updateFile', + data: [ + { + filename, + code: fileData.code, + }, + ], + }); + } +} + +interface EditorHistoryRecord { + data: Array>; + time: number; + message: string; +} + +/** + * TODO: 实现上需要要 TangoHistory 合并 + */ +class EditorHistory { + _records: EditorHistoryRecord[] = []; + _index = 0; + _maxSize = 100; + + get size() { + return this._records.length; + } + + push(payload: Omit) { + if (this._index < this.size - 1) { + this._records = this._records.slice(0, this._index + 1); + } + this._index = this.size; + this._records.push({ + time: Date.now(), + ...payload, + }); + + if (this.size > this._maxSize) { + this._records.splice(0, this.size - this._maxSize); + this._index = this.size - 1; + } + } + + clear() { + this._records = []; + this._index = 0; } }