Skip to content

Commit cd47341

Browse files
zhangtengjinwewoor
authored andcommitted
feat: extract logic to extensions
extract logic to extensions
1 parent 69bbb75 commit cd47341

File tree

8 files changed

+284
-204
lines changed

8 files changed

+284
-204
lines changed

src/controller/editor.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
IStatusBarService,
2626
StatusBarService,
2727
} from 'mo/services';
28+
import { FolderTreeEvent } from 'mo/model/workbench/explorer/folderTree';
2829

2930
export interface IEditorController {
3031
groupSplitPos?: string[];
@@ -233,7 +234,8 @@ export class EditorController extends Controller implements IEditorController {
233234
},
234235
groupId
235236
);
236-
this.folderTreeService.updateFileContent(
237+
this.emit(
238+
FolderTreeEvent.onUpdateFileContent,
237239
current?.tab?.id as any,
238240
newValue
239241
);

src/controller/explorer/folderTree.tsx

+44-63
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import 'reflect-metadata';
22
import * as React from 'react';
33
import { container, singleton } from 'tsyringe';
44
import { Controller } from 'mo/react/controller';
5-
65
import { ITreeNodeItem, FileTypes } from 'mo/components/tree';
76
import { IMenuItem } from 'mo/components/menu';
87
import Modal from 'mo/components/dialog';
@@ -21,18 +20,11 @@ import {
2120
ADD_ROOT_FOLDER_COMMAND_ID,
2221
FolderTreeEvent,
2322
} from 'mo/model';
24-
import {
25-
EditorService,
26-
FolderTreeService,
27-
IEditorService,
28-
IFolderTreeService,
29-
} from 'mo/services';
23+
import { FolderTreeService, IFolderTreeService } from 'mo/services';
3024

3125
const confirm = Modal.confirm;
3226

3327
export interface IFolderTreeController {
34-
readonly onSelectFile?: (file: ITreeNodeItem, isUpdate?: boolean) => void;
35-
readonly onDropTree?: (treeNode: ITreeNodeItem[]) => void;
3628
readonly onClickContextMenu?: (
3729
e: React.MouseEvent,
3830
item: IMenuItem,
@@ -44,68 +36,70 @@ export interface IFolderTreeController {
4436
treeNode: ITreeNodeItem
4537
) => IMenuItem[];
4638
readonly getInputEvent?: (events: IFolderInputEvent) => IFolderInputEvent;
39+
readonly onNewFile?: (id: number) => void;
40+
readonly onNewFolder?: (id: number) => void;
41+
readonly onRename?: (id: number) => void;
42+
readonly onDelete?: (id: number) => void;
43+
readonly onUpdateFileName?: (file: ITreeNodeItem) => void;
44+
readonly onUpdateFileContent?: (id: number, value?: string) => void;
45+
readonly onSelectFile?: (file: ITreeNodeItem, isUpdate?: boolean) => void;
46+
readonly onDropTree?: (treeNode: ITreeNodeItem[]) => void;
4747
}
4848

4949
@singleton()
5050
export class FolderTreeController
5151
extends Controller
5252
implements IFolderTreeController {
5353
private readonly folderTreeService: IFolderTreeService;
54-
private readonly editorService: IEditorService;
5554
constructor() {
5655
super();
5756
this.folderTreeService = container.resolve(FolderTreeService);
58-
this.editorService = container.resolve(EditorService);
5957
this.initView();
6058
}
6159

6260
private initView() {}
6361

62+
public readonly getInputEvent = (
63+
events: IFolderInputEvent
64+
): IFolderInputEvent => {
65+
return events;
66+
};
67+
68+
public onRename = (id: number) => {
69+
this.emit(FolderTreeEvent.onRename, id);
70+
};
71+
72+
public onDelete = (id: number) => {
73+
this.emit(FolderTreeEvent.onDelete, id);
74+
};
75+
76+
public onNewFile = (id: number) => {
77+
this.emit(FolderTreeEvent.onNewFile, id);
78+
};
79+
80+
public onNewFolder = (id: number) => {
81+
this.emit(FolderTreeEvent.onNewFolder, id);
82+
};
83+
84+
public onUpdateFileName = (file: ITreeNodeItem) => {
85+
this.emit(FolderTreeEvent.onUpdateFileName, file);
86+
};
87+
88+
public onUpdateFileContent = (id: number, value?: string) => {
89+
this.emit(FolderTreeEvent.onUpdateFileContent, id, value);
90+
};
91+
6492
public readonly onSelectFile = (
6593
file: ITreeNodeItem,
6694
isUpdate?: boolean
6795
) => {
68-
const { fileType, isEditable } = file;
69-
const isFile = fileType === FileTypes.file;
70-
this.folderTreeService.setActive(file?.id);
71-
if (!isFile || isEditable) return;
72-
const tabData = {
73-
...file,
74-
id: `${file.id}`?.split('_')?.[0],
75-
modified: false,
76-
data: {
77-
value: file.content,
78-
path: 'desktop/moslecule/editor1',
79-
language: 'sql',
80-
},
81-
};
82-
83-
const { id, data = [] } =
84-
this.editorService.getState()?.current || ({} as any);
85-
if (isUpdate) {
86-
const tabId = file.id;
87-
const index = data?.findIndex((tab) => tab.id == tabId);
88-
if (index > -1) {
89-
if (id) this.editorService.updateTab(tabData, id);
90-
} else {
91-
this.editorService.open(tabData);
92-
}
93-
} else {
94-
this.editorService.open(tabData);
95-
}
96-
this.emit(FolderTreeEvent.onSelectFile, tabData, isUpdate);
96+
this.emit(FolderTreeEvent.onSelectFile, file, isUpdate);
9797
};
9898

9999
public readonly onDropTree = (treeNode: ITreeNodeItem[]) => {
100100
this.folderTreeService.onDropTree(treeNode);
101101
};
102102

103-
public readonly getInputEvent = (
104-
events: IFolderInputEvent
105-
): IFolderInputEvent => {
106-
return events;
107-
};
108-
109103
public readonly onClickContextMenu = (
110104
e: React.MouseEvent,
111105
item: IMenuItem,
@@ -118,38 +112,25 @@ export class FolderTreeController
118112
console.log('onClickContextMenu => Item', item);
119113
switch (menuId) {
120114
case RENAME_COMMAND_ID: {
121-
this.folderTreeService.rename(nodeId, () => {
122-
events?.setValue?.(name);
123-
events?.onFocus();
124-
});
115+
this.onRename(nodeId);
125116
break;
126117
}
127118
case DELETE_COMMAND_ID: {
128119
confirm({
129120
title: `Are you sure you want to delete '${name}' ?`,
130121
content: 'This action is irreversible!',
131122
onOk() {
132-
ctx.folderTreeService.delete(nodeId, () => {
133-
// TODO Refactor the below, there needs listen to the CloseTab by the editorService
134-
// ctx.editorController!.onCloseTab(
135-
// `${nodeId}`,
136-
// ctx.editorService.getState()?.current?.id
137-
// );
138-
});
123+
ctx.onDelete(nodeId);
139124
},
140125
});
141126
break;
142127
}
143128
case NEW_FILE_COMMAND_ID: {
144-
this.folderTreeService.newFile(nodeId, () => {
145-
events?.onFocus();
146-
});
129+
this.onNewFile(nodeId);
147130
break;
148131
}
149132
case NEW_FOLDER_COMMAND_ID: {
150-
this.folderTreeService.newFolder(nodeId, () => {
151-
events?.onFocus();
152-
});
133+
this.onNewFolder(nodeId);
153134
break;
154135
}
155136
case REMOVE_COMMAND_ID: {

src/extensions/folderTree/index.tsx

+159
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
import { folderTreeService, editorService } from 'mo';
2+
import { IExtension } from 'mo/model/extension';
3+
import { ITreeNodeItem, FileTypes, FileType } from 'mo/components/tree';
4+
import { TreeNodeModel } from 'mo/model';
5+
export const ExtendFolderTree: IExtension = {
6+
activate() {
7+
const createTargetNodeById = (
8+
id: number,
9+
treeInstance,
10+
extra?: ITreeNodeItem
11+
) => {
12+
const currentIndex = treeInstance.getIndex(id);
13+
// If the node type of the current id is a file, insert it at the parent node above it
14+
if (currentIndex?.node?.fileType === FileTypes.file) {
15+
treeInstance.prepend(
16+
new TreeNodeModel(extra),
17+
currentIndex?.parent
18+
);
19+
} else {
20+
treeInstance.append(new TreeNodeModel(extra), id);
21+
}
22+
};
23+
24+
folderTreeService.onNewFile((id: number) => {
25+
const { folderTree } = folderTreeService.getState();
26+
const cloneData: ITreeNodeItem[] = folderTree?.data || [];
27+
const { tree, index } = folderTreeService.getCurrentRootFolderInfo(
28+
id
29+
);
30+
createTargetNodeById(id, tree, {
31+
isEditable: true,
32+
});
33+
if (index > -1) cloneData[index] = tree.obj;
34+
folderTreeService.setState({
35+
folderTree: { ...folderTree, data: cloneData },
36+
});
37+
});
38+
39+
folderTreeService.onNewFolder((id: number) => {
40+
const { folderTree } = folderTreeService.getState();
41+
const cloneData: ITreeNodeItem[] = folderTree?.data || [];
42+
const { tree, index } = folderTreeService.getCurrentRootFolderInfo(
43+
id
44+
);
45+
createTargetNodeById(id, tree, {
46+
fileType: FileTypes.folder as FileType,
47+
isEditable: true,
48+
});
49+
if (index > -1) cloneData[index] = tree.obj;
50+
folderTreeService.setState({
51+
folderTree: { ...folderTree, data: cloneData },
52+
});
53+
});
54+
55+
folderTreeService.onDelete((id: number) => {
56+
const { folderTree } = folderTreeService.getState();
57+
const cloneData: ITreeNodeItem[] = folderTree?.data || [];
58+
const { tree, index } = folderTreeService.getCurrentRootFolderInfo(
59+
id
60+
);
61+
tree.remove(id);
62+
if (index > -1) cloneData[index] = tree.obj;
63+
folderTreeService.setState({
64+
folderTree: { ...folderTree, data: cloneData },
65+
});
66+
});
67+
68+
folderTreeService.onRename((id: number) => {
69+
const { folderTree } = folderTreeService.getState();
70+
const cloneData: ITreeNodeItem[] = folderTree?.data || [];
71+
const { tree, index } = folderTreeService.getCurrentRootFolderInfo(
72+
id
73+
);
74+
tree.update(id, {
75+
isEditable: true,
76+
});
77+
if (index > -1) cloneData[index] = tree.obj;
78+
folderTreeService.setState({
79+
folderTree: { ...folderTree, data: cloneData },
80+
});
81+
});
82+
83+
folderTreeService.onSelectFile(
84+
(file: ITreeNodeItem, isUpdate?: boolean) => {
85+
const { fileType, isEditable } = file;
86+
const isFile = fileType === FileTypes.file;
87+
folderTreeService.setActive(file?.id);
88+
if (!isFile || isEditable) return;
89+
const tabData = {
90+
...file,
91+
id: `${file.id}`?.split('_')?.[0],
92+
modified: false,
93+
data: {
94+
value: file.content,
95+
path: 'desktop/moslecule/editor1',
96+
language: 'sql',
97+
},
98+
};
99+
100+
const { id, data = [] } =
101+
editorService.getState()?.current || ({} as any);
102+
if (isUpdate) {
103+
const tabId = file.id;
104+
const index = data?.findIndex((tab) => tab.id == tabId);
105+
if (index > -1) {
106+
if (id) editorService.updateTab(tabData, id);
107+
} else {
108+
editorService.open(tabData);
109+
}
110+
} else {
111+
editorService.open(tabData);
112+
}
113+
}
114+
);
115+
116+
folderTreeService.onUpdateFileName((file: ITreeNodeItem) => {
117+
const { folderTree } = folderTreeService.getState();
118+
const { id, name, fileType } = file as any;
119+
const cloneData: ITreeNodeItem[] = folderTree?.data || [];
120+
const { tree, index } = folderTreeService.getCurrentRootFolderInfo(
121+
id
122+
);
123+
if (name) {
124+
tree.update(id, {
125+
...file,
126+
icon: folderTreeService.getFileIconByExtensionName(
127+
name,
128+
fileType
129+
),
130+
isEditable: false,
131+
});
132+
} else {
133+
tree.remove(id);
134+
}
135+
if (index > -1) cloneData[index] = tree.obj;
136+
folderTreeService.setState({
137+
folderTree: { ...folderTree, data: cloneData },
138+
});
139+
if (file?.fileType === FileTypes.file && file.name) {
140+
// emit onSelectFile
141+
}
142+
});
143+
144+
folderTreeService.onUpdateFileContent((id: number, value?: string) => {
145+
const { folderTree } = folderTreeService.getState();
146+
const cloneData: ITreeNodeItem[] = folderTree?.data || [];
147+
const { tree, index } = folderTreeService.getCurrentRootFolderInfo(
148+
id
149+
);
150+
tree.update(id, {
151+
content: value,
152+
});
153+
if (index > -1) cloneData[index] = tree.obj;
154+
folderTreeService.setState({
155+
folderTree: { ...folderTree, data: cloneData },
156+
});
157+
});
158+
},
159+
};

src/extensions/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { ExtendStatusBar } from './statusBar';
22
import { defaultColorThemeExtension } from './theme-defaults';
33
import { monokaiColorThemeExtension } from './theme-monokai';
44
import { paleNightColorThemeExtension } from './vscode-palenight-theme';
5+
import { ExtendFolderTree } from './folderTree';
56

67
/**
78
* Default extensions
@@ -11,4 +12,5 @@ export const defaultExtensions = [
1112
defaultColorThemeExtension,
1213
monokaiColorThemeExtension,
1314
paleNightColorThemeExtension,
15+
ExtendFolderTree,
1416
];

src/model/workbench/explorer/folderTree.tsx

+6
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ import { randomId } from 'mo/common/utils';
77
export enum FolderTreeEvent {
88
onClick = 'folderTree.onClick',
99
onSelectFile = 'folderTree.onSelectFile',
10+
onNewFile = 'folderTree.onNewFile',
11+
onNewFolder = 'folderTree.onNewFolder',
12+
onDelete = 'folderTree.onDelete',
13+
onRename = 'folderTree.onRename',
14+
onUpdateFileName = 'folderTree.onUpdateFileName',
15+
onUpdateFileContent = 'folderTree.onUpdateFileContent',
1016
}
1117

1218
export interface IFolderInputEvent {

0 commit comments

Comments
 (0)