feat: add editorHistory

This commit is contained in:
wwsun
2024-07-23 16:36:28 +08:00
parent 72f2c86619
commit c239bc367f
2 changed files with 138 additions and 13 deletions

View File

@@ -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();

View File

@@ -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<Partial<AddFilePayload>>;
time: number;
message: string;
}
/**
* TODO: 实现上需要要 TangoHistory 合并
*/
class EditorHistory {
_records: EditorHistoryRecord[] = [];
_index = 0;
_maxSize = 100;
get size() {
return this._records.length;
}
push(payload: Omit<EditorHistoryRecord, 'time'>) {
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;
}
}