Skip to content

Commit

Permalink
feat: extract logic to extensions
Browse files Browse the repository at this point in the history
extract logic to extensions
  • Loading branch information
zhangtengjin authored and wewoor committed Apr 16, 2021
1 parent 69bbb75 commit cd47341
Show file tree
Hide file tree
Showing 8 changed files with 284 additions and 204 deletions.
4 changes: 3 additions & 1 deletion src/controller/editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
IStatusBarService,
StatusBarService,
} from 'mo/services';
import { FolderTreeEvent } from 'mo/model/workbench/explorer/folderTree';

export interface IEditorController {
groupSplitPos?: string[];
Expand Down Expand Up @@ -233,7 +234,8 @@ export class EditorController extends Controller implements IEditorController {
},
groupId
);
this.folderTreeService.updateFileContent(
this.emit(
FolderTreeEvent.onUpdateFileContent,
current?.tab?.id as any,
newValue
);
Expand Down
107 changes: 44 additions & 63 deletions src/controller/explorer/folderTree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import 'reflect-metadata';
import * as React from 'react';
import { container, singleton } from 'tsyringe';
import { Controller } from 'mo/react/controller';

import { ITreeNodeItem, FileTypes } from 'mo/components/tree';
import { IMenuItem } from 'mo/components/menu';
import Modal from 'mo/components/dialog';
Expand All @@ -21,18 +20,11 @@ import {
ADD_ROOT_FOLDER_COMMAND_ID,
FolderTreeEvent,
} from 'mo/model';
import {
EditorService,
FolderTreeService,
IEditorService,
IFolderTreeService,
} from 'mo/services';
import { FolderTreeService, IFolderTreeService } from 'mo/services';

const confirm = Modal.confirm;

export interface IFolderTreeController {
readonly onSelectFile?: (file: ITreeNodeItem, isUpdate?: boolean) => void;
readonly onDropTree?: (treeNode: ITreeNodeItem[]) => void;
readonly onClickContextMenu?: (
e: React.MouseEvent,
item: IMenuItem,
Expand All @@ -44,68 +36,70 @@ export interface IFolderTreeController {
treeNode: ITreeNodeItem
) => IMenuItem[];
readonly getInputEvent?: (events: IFolderInputEvent) => IFolderInputEvent;
readonly onNewFile?: (id: number) => void;
readonly onNewFolder?: (id: number) => void;
readonly onRename?: (id: number) => void;
readonly onDelete?: (id: number) => void;
readonly onUpdateFileName?: (file: ITreeNodeItem) => void;
readonly onUpdateFileContent?: (id: number, value?: string) => void;
readonly onSelectFile?: (file: ITreeNodeItem, isUpdate?: boolean) => void;
readonly onDropTree?: (treeNode: ITreeNodeItem[]) => void;
}

@singleton()
export class FolderTreeController
extends Controller
implements IFolderTreeController {
private readonly folderTreeService: IFolderTreeService;
private readonly editorService: IEditorService;
constructor() {
super();
this.folderTreeService = container.resolve(FolderTreeService);
this.editorService = container.resolve(EditorService);
this.initView();
}

private initView() {}

public readonly getInputEvent = (
events: IFolderInputEvent
): IFolderInputEvent => {
return events;
};

public onRename = (id: number) => {
this.emit(FolderTreeEvent.onRename, id);
};

public onDelete = (id: number) => {
this.emit(FolderTreeEvent.onDelete, id);
};

public onNewFile = (id: number) => {
this.emit(FolderTreeEvent.onNewFile, id);
};

public onNewFolder = (id: number) => {
this.emit(FolderTreeEvent.onNewFolder, id);
};

public onUpdateFileName = (file: ITreeNodeItem) => {
this.emit(FolderTreeEvent.onUpdateFileName, file);
};

public onUpdateFileContent = (id: number, value?: string) => {
this.emit(FolderTreeEvent.onUpdateFileContent, id, value);
};

public readonly onSelectFile = (
file: ITreeNodeItem,
isUpdate?: boolean
) => {
const { fileType, isEditable } = file;
const isFile = fileType === FileTypes.file;
this.folderTreeService.setActive(file?.id);
if (!isFile || isEditable) return;
const tabData = {
...file,
id: `${file.id}`?.split('_')?.[0],
modified: false,
data: {
value: file.content,
path: 'desktop/moslecule/editor1',
language: 'sql',
},
};

const { id, data = [] } =
this.editorService.getState()?.current || ({} as any);
if (isUpdate) {
const tabId = file.id;
const index = data?.findIndex((tab) => tab.id == tabId);
if (index > -1) {
if (id) this.editorService.updateTab(tabData, id);
} else {
this.editorService.open(tabData);
}
} else {
this.editorService.open(tabData);
}
this.emit(FolderTreeEvent.onSelectFile, tabData, isUpdate);
this.emit(FolderTreeEvent.onSelectFile, file, isUpdate);
};

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

public readonly getInputEvent = (
events: IFolderInputEvent
): IFolderInputEvent => {
return events;
};

public readonly onClickContextMenu = (
e: React.MouseEvent,
item: IMenuItem,
Expand All @@ -118,38 +112,25 @@ export class FolderTreeController
console.log('onClickContextMenu => Item', item);
switch (menuId) {
case RENAME_COMMAND_ID: {
this.folderTreeService.rename(nodeId, () => {
events?.setValue?.(name);
events?.onFocus();
});
this.onRename(nodeId);
break;
}
case DELETE_COMMAND_ID: {
confirm({
title: `Are you sure you want to delete '${name}' ?`,
content: 'This action is irreversible!',
onOk() {
ctx.folderTreeService.delete(nodeId, () => {
// TODO Refactor the below, there needs listen to the CloseTab by the editorService
// ctx.editorController!.onCloseTab(
// `${nodeId}`,
// ctx.editorService.getState()?.current?.id
// );
});
ctx.onDelete(nodeId);
},
});
break;
}
case NEW_FILE_COMMAND_ID: {
this.folderTreeService.newFile(nodeId, () => {
events?.onFocus();
});
this.onNewFile(nodeId);
break;
}
case NEW_FOLDER_COMMAND_ID: {
this.folderTreeService.newFolder(nodeId, () => {
events?.onFocus();
});
this.onNewFolder(nodeId);
break;
}
case REMOVE_COMMAND_ID: {
Expand Down
159 changes: 159 additions & 0 deletions src/extensions/folderTree/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import { folderTreeService, editorService } from 'mo';
import { IExtension } from 'mo/model/extension';
import { ITreeNodeItem, FileTypes, FileType } from 'mo/components/tree';
import { TreeNodeModel } from 'mo/model';
export const ExtendFolderTree: IExtension = {
activate() {
const createTargetNodeById = (
id: number,
treeInstance,
extra?: ITreeNodeItem
) => {
const currentIndex = treeInstance.getIndex(id);
// If the node type of the current id is a file, insert it at the parent node above it
if (currentIndex?.node?.fileType === FileTypes.file) {
treeInstance.prepend(
new TreeNodeModel(extra),
currentIndex?.parent
);
} else {
treeInstance.append(new TreeNodeModel(extra), id);
}
};

folderTreeService.onNewFile((id: number) => {
const { folderTree } = folderTreeService.getState();
const cloneData: ITreeNodeItem[] = folderTree?.data || [];
const { tree, index } = folderTreeService.getCurrentRootFolderInfo(
id
);
createTargetNodeById(id, tree, {
isEditable: true,
});
if (index > -1) cloneData[index] = tree.obj;
folderTreeService.setState({
folderTree: { ...folderTree, data: cloneData },
});
});

folderTreeService.onNewFolder((id: number) => {
const { folderTree } = folderTreeService.getState();
const cloneData: ITreeNodeItem[] = folderTree?.data || [];
const { tree, index } = folderTreeService.getCurrentRootFolderInfo(
id
);
createTargetNodeById(id, tree, {
fileType: FileTypes.folder as FileType,
isEditable: true,
});
if (index > -1) cloneData[index] = tree.obj;
folderTreeService.setState({
folderTree: { ...folderTree, data: cloneData },
});
});

folderTreeService.onDelete((id: number) => {
const { folderTree } = folderTreeService.getState();
const cloneData: ITreeNodeItem[] = folderTree?.data || [];
const { tree, index } = folderTreeService.getCurrentRootFolderInfo(
id
);
tree.remove(id);
if (index > -1) cloneData[index] = tree.obj;
folderTreeService.setState({
folderTree: { ...folderTree, data: cloneData },
});
});

folderTreeService.onRename((id: number) => {
const { folderTree } = folderTreeService.getState();
const cloneData: ITreeNodeItem[] = folderTree?.data || [];
const { tree, index } = folderTreeService.getCurrentRootFolderInfo(
id
);
tree.update(id, {
isEditable: true,
});
if (index > -1) cloneData[index] = tree.obj;
folderTreeService.setState({
folderTree: { ...folderTree, data: cloneData },
});
});

folderTreeService.onSelectFile(
(file: ITreeNodeItem, isUpdate?: boolean) => {
const { fileType, isEditable } = file;
const isFile = fileType === FileTypes.file;
folderTreeService.setActive(file?.id);
if (!isFile || isEditable) return;
const tabData = {
...file,
id: `${file.id}`?.split('_')?.[0],
modified: false,
data: {
value: file.content,
path: 'desktop/moslecule/editor1',
language: 'sql',
},
};

const { id, data = [] } =
editorService.getState()?.current || ({} as any);
if (isUpdate) {
const tabId = file.id;
const index = data?.findIndex((tab) => tab.id == tabId);
if (index > -1) {
if (id) editorService.updateTab(tabData, id);
} else {
editorService.open(tabData);
}
} else {
editorService.open(tabData);
}
}
);

folderTreeService.onUpdateFileName((file: ITreeNodeItem) => {
const { folderTree } = folderTreeService.getState();
const { id, name, fileType } = file as any;
const cloneData: ITreeNodeItem[] = folderTree?.data || [];
const { tree, index } = folderTreeService.getCurrentRootFolderInfo(
id
);
if (name) {
tree.update(id, {
...file,
icon: folderTreeService.getFileIconByExtensionName(
name,
fileType
),
isEditable: false,
});
} else {
tree.remove(id);
}
if (index > -1) cloneData[index] = tree.obj;
folderTreeService.setState({
folderTree: { ...folderTree, data: cloneData },
});
if (file?.fileType === FileTypes.file && file.name) {
// emit onSelectFile
}
});

folderTreeService.onUpdateFileContent((id: number, value?: string) => {
const { folderTree } = folderTreeService.getState();
const cloneData: ITreeNodeItem[] = folderTree?.data || [];
const { tree, index } = folderTreeService.getCurrentRootFolderInfo(
id
);
tree.update(id, {
content: value,
});
if (index > -1) cloneData[index] = tree.obj;
folderTreeService.setState({
folderTree: { ...folderTree, data: cloneData },
});
});
},
};
2 changes: 2 additions & 0 deletions src/extensions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ExtendStatusBar } from './statusBar';
import { defaultColorThemeExtension } from './theme-defaults';
import { monokaiColorThemeExtension } from './theme-monokai';
import { paleNightColorThemeExtension } from './vscode-palenight-theme';
import { ExtendFolderTree } from './folderTree';

/**
* Default extensions
Expand All @@ -11,4 +12,5 @@ export const defaultExtensions = [
defaultColorThemeExtension,
monokaiColorThemeExtension,
paleNightColorThemeExtension,
ExtendFolderTree,
];
6 changes: 6 additions & 0 deletions src/model/workbench/explorer/folderTree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ import { randomId } from 'mo/common/utils';
export enum FolderTreeEvent {
onClick = 'folderTree.onClick',
onSelectFile = 'folderTree.onSelectFile',
onNewFile = 'folderTree.onNewFile',
onNewFolder = 'folderTree.onNewFolder',
onDelete = 'folderTree.onDelete',
onRename = 'folderTree.onRename',
onUpdateFileName = 'folderTree.onUpdateFileName',
onUpdateFileContent = 'folderTree.onUpdateFileContent',
}

export interface IFolderInputEvent {
Expand Down
Loading

0 comments on commit cd47341

Please sign in to comment.