Skip to content

Commit ce3c202

Browse files
authored
feat(i18n): support basic il8n feature (#170)
* feat(i18n): support basic il8n feature 1. built-in en, zh-CN locales; 2. load the model data in extensions' re #106, re #107 * fix: remove useless * refactor: rename locale to localeId * refactor: rename local to locale * refactor: decorate the menuBarController with private readonly * refactor: remove the useless optional chaining * fix: keyof the locale source type * refactor: rename the locale to source * refactor: rename the id of ILocalizeProps as sourceKey
1 parent c87e31f commit ce3c202

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+1293
-591
lines changed

build/webpack.css.js

+7
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,13 @@ module.exports = function () {
109109
ignore: ['**/*.ts', '**/*.tsx'],
110110
},
111111
},
112+
{
113+
from: path.resolve(
114+
__dirname,
115+
'../src/i18n/source/zh-CN.json'
116+
),
117+
to: path.resolve(__dirname, '../esm/i18n/source/'),
118+
},
112119
],
113120
}),
114121
],

src/components/actionBar/index.tsx

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
import * as React from 'react';
2-
import { useCallback, useEffect } from 'react';
2+
import { useCallback, useEffect, useRef } from 'react';
33
import {
44
prefixClaName,
55
classNames,
66
getBEMElement,
77
getBEMModifier,
88
} from 'mo/common/className';
99
import { useContextMenu } from 'mo/components/contextMenu';
10-
import { select } from 'mo/common/dom';
1110
import { IMenuItemProps, Menu } from 'mo/components/menu';
1211
import { mergeFunctions } from 'mo/common/utils';
1312

1413
export interface IActionBarItemProps<T = any> {
1514
id?: string;
16-
name?: string;
15+
name?: ReactNode;
1716
title?: string;
1817
iconName?: string;
1918
disabled?: boolean;
@@ -60,6 +59,8 @@ export function ActionBarItem(props: IActionBarItemProps) {
6059
} = props;
6160
const disabled = props.disabled ? itemDisabledClassName : null;
6261
const checked = props.checked ? itemCheckedClassName : null;
62+
const refItem = useRef(null);
63+
6364
const claNames = classNames(
6465
labelClassName,
6566
'codicon',
@@ -84,7 +85,7 @@ export function ActionBarItem(props: IActionBarItemProps) {
8485
useEffect(() => {
8586
if (contextMenu.length > 0) {
8687
contextViewMenu = useContextMenu({
87-
anchor: select(`#${id}`),
88+
anchor: refItem.current,
8889
render: renderContextMenu,
8990
});
9091
}
@@ -107,6 +108,7 @@ export function ActionBarItem(props: IActionBarItemProps) {
107108
return (
108109
<li
109110
id={id}
111+
ref={refItem}
110112
className={classNames(itemClassName, disabled)}
111113
onClick={onClickItem}
112114
data-id={data.id}

src/components/icon/index.tsx

+5-3
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ export interface IIconProps extends ComponentProps<'span'> {
88
onClick?: (e: React.MouseEvent) => void;
99
}
1010

11-
export function Icon(props: IIconProps) {
12-
const { className, type, ...restProps } = props;
11+
export function Icon(props: React.PropsWithChildren<IIconProps>) {
12+
const { className, type, children, ...restProps } = props;
1313
return (
1414
<span
1515
className={classNames(
@@ -18,6 +18,8 @@ export function Icon(props: IIconProps) {
1818
prefixClaName(type, 'codicon')
1919
)}
2020
{...restProps}
21-
></span>
21+
>
22+
{children}
23+
</span>
2224
);
2325
}

src/components/menu/menuItem.tsx

+6-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,12 @@ export function MenuItem(props: React.PropsWithChildren<IMenuItemProps>) {
6060
{...custom}
6161
>
6262
<a className={menuContentClassName}>
63-
<Icon className={checkClassName} type={icon || ''} />
63+
<Icon
64+
className={checkClassName}
65+
type={typeof icon === 'string' ? icon : ''}
66+
>
67+
{typeof icon === 'object' ? icon : ''}
68+
</Icon>
6469
<span className={labelClassName} title={name as string}>
6570
{render ? render(props) : children}
6671
</span>

src/controller/activityBar.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -90,32 +90,32 @@ export class ActivityBarController
9090
const contextMenuId = item?.id;
9191
switch (contextMenuId) {
9292
// activityBar contextMenu
93-
case CONTEXT_MENU_MENU.id: {
93+
case CONTEXT_MENU_MENU: {
9494
this.menuBarService.showHide();
9595
break;
9696
}
97-
case CONTEXT_MENU_EXPLORER.id: {
97+
case CONTEXT_MENU_EXPLORER: {
9898
this.activityBarService.toggleBar(contextMenuId);
9999
break;
100100
}
101-
case CONTEXT_MENU_SEARCH.id: {
101+
case CONTEXT_MENU_SEARCH: {
102102
this.activityBarService.toggleBar(contextMenuId);
103103
break;
104104
}
105-
case CONTEXT_MENU_HIDE.id: {
105+
case CONTEXT_MENU_HIDE: {
106106
this.activityBarService.showHide();
107107
break;
108108
}
109109
// manage button contextMenu
110-
case CONTEXT_MENU_COMMAND_PALETTE.id: {
110+
case CONTEXT_MENU_COMMAND_PALETTE: {
111111
this.gotoQuickCommand();
112112
break;
113113
}
114-
case CONTEXT_MENU_SETTINGS.id: {
114+
case CONTEXT_MENU_SETTINGS: {
115115
this.settingsService.openSettingsInEditor();
116116
break;
117117
}
118-
case CONTEXT_MENU_COLOR_THEME.id: {
118+
case CONTEXT_MENU_COLOR_THEME: {
119119
this.onSelectColorTheme();
120120
break;
121121
}

src/controller/editor.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ export class EditorController extends Controller implements IEditorController {
180180
);
181181
};
182182

183+
// TODO: Remove the below action register ?, because of the monaco Editor have integrated the undo/redo action
183184
private registerActions = (editorInstance) => {
184185
undoRedoMenu.forEach(({ id, label }) => {
185186
editorInstance?.addAction({

src/controller/explorer/explorer.tsx

+24-9
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,14 @@ import { Explorer, FolderTreeView } from 'mo/workbench/sidebar/explore';
77
import { IMenuItemProps } from 'mo/components/menu';
88
import { MENU_VIEW_SIDEBAR } from 'mo/model/workbench/menuBar';
99
import { IActivityBarItem } from 'mo/model/workbench/activityBar';
10-
import { ExplorerEvent } from 'mo/model/workbench/explorer/explorer';
1110
import {
12-
SAMPLE_FOLDER_PANEL,
11+
builtInExplorerActivityItem,
12+
builtInExplorerFolderPanel,
13+
builtInExplorerEditorPanel,
14+
ExplorerEvent,
15+
builtInExplorerHeaderToolbar,
16+
} from 'mo/model/workbench/explorer/explorer';
17+
import {
1318
NEW_FILE_COMMAND_ID,
1419
NEW_FOLDER_COMMAND_ID,
1520
EXPLORER_ACTIVITY_ITEM,
@@ -65,9 +70,10 @@ export class ExplorerController
6570
const ctx = this;
6671
const state = this.activityBarService.getState();
6772
const sideBarState = this.sidebarService.getState();
73+
const { data = [] } = state;
6874
this.activityBarService.setState({
69-
selected: EXPLORER_ACTIVITY_ITEM.id,
70-
data: [...state.data!, EXPLORER_ACTIVITY_ITEM],
75+
selected: EXPLORER_ACTIVITY_ITEM,
76+
data: [...data, builtInExplorerActivityItem()],
7177
});
7278

7379
const explorerEvent = {
@@ -89,7 +95,7 @@ export class ExplorerController
8995

9096
this.activityBarService.onSelect((e, item: IActivityBarItem) => {
9197
const { hidden } = this.sidebarService.getState();
92-
if (item.id === EXPLORER_ACTIVITY_ITEM.id) {
98+
if (item.id === EXPLORER_ACTIVITY_ITEM) {
9399
const isShow = hidden ? !hidden : hidden;
94100
this.sidebarService.setState({
95101
current: explorePane.id,
@@ -105,10 +111,16 @@ export class ExplorerController
105111
current: explorePane.id,
106112
panes: [...sideBarState.panes!, explorePane],
107113
});
108-
109-
this.explorerService.addPanel([
110-
{ ...SAMPLE_FOLDER_PANEL, renderPanel: this.renderFolderTree },
111-
]);
114+
this.explorerService.setState({
115+
data: [
116+
{ ...builtInExplorerEditorPanel() },
117+
{
118+
...builtInExplorerFolderPanel(),
119+
renderPanel: this.renderFolderTree,
120+
},
121+
],
122+
headerToolBar: builtInExplorerHeaderToolbar(),
123+
});
112124
}
113125

114126
private createFileOrFolder = (type) => {
@@ -165,3 +177,6 @@ export class ExplorerController
165177
);
166178
};
167179
}
180+
181+
// Register singleton
182+
container.resolve(ExplorerController);

src/controller/explorer/folderTree.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -179,3 +179,6 @@ export class FolderTreeController
179179
return menu;
180180
};
181181
}
182+
183+
// Register singleton
184+
container.resolve(FolderTreeController);

src/controller/explorer/outline.tsx

+10-3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Controller } from 'mo/react/controller';
33
import { container, singleton } from 'tsyringe';
44
import React from 'react';
55
import { ExplorerService, IExplorerService } from 'mo/services';
6+
import { localize } from 'mo/i18n/localize';
67

78
export interface IOutlineController {}
89

@@ -21,16 +22,19 @@ export class OutlineController
2122
private initView() {
2223
const outlinePanel = {
2324
id: 'outline',
24-
name: 'OUTLINE',
25+
name: localize('sidebar.explore.outline', 'OUTLINE'),
2526
toolbar: [
2627
{
2728
id: 'outline-collapse',
28-
title: 'Collapse All',
29+
title: localize('toolbar.collapseAll', 'Collapse All'),
2930
iconName: 'codicon-collapse-all',
3031
},
3132
{
3233
id: 'outline-more',
33-
title: 'More Actions...',
34+
title: localize(
35+
'sidebar.explore.outlineMore',
36+
'More Actions...'
37+
),
3438
iconName: 'codicon-ellipsis',
3539
},
3640
],
@@ -42,3 +46,6 @@ export class OutlineController
4246
// console.log('onClick:', panelService);
4347
};
4448
}
49+
50+
// Register singleton
51+
container.resolve(OutlineController);

src/controller/index.ts

+4-16
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,7 @@ export * from './settings';
88
export * from './sidebar';
99
export * from './statusBar';
1010
export * from './workbench';
11-
12-
import { container } from 'tsyringe';
13-
import { ExplorerController } from './explorer/explorer';
14-
import { FolderTreeController } from './explorer/folderTree';
15-
import { SearchController } from './search/search';
16-
import { NotificationController } from './notification';
17-
import { SettingsController } from './settings';
18-
import { ProblemsController } from './problems';
19-
import { MenuBarController } from './menuBar';
20-
export const explorerController = container.resolve(ExplorerController);
21-
export const searchController = container.resolve(SearchController);
22-
export const folderTreeController = container.resolve(FolderTreeController);
23-
export const notificationController = container.resolve(NotificationController);
24-
export const settingController = container.resolve(SettingsController);
25-
export const problemsController = container.resolve(ProblemsController);
26-
export const menuBarController = container.resolve(MenuBarController);
11+
export * from './explorer/explorer';
12+
export * from './explorer/folderTree';
13+
export * from './explorer/outline';
14+
export * from './search/search';

src/controller/notification.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,6 @@ export class NotificationController
109109
this._notificationPane = container;
110110
}
111111
}
112+
113+
// Register a singleton
114+
container.resolve(NotificationController);

src/controller/panel.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ export class PanelController extends Controller implements IPanelController {
3838
e: React.MouseEvent,
3939
item: IActionBarItemProps
4040
): void => {
41-
if (item.id === PANEL_TOOLBOX_CLOSE.id) {
41+
if (item.id === PANEL_TOOLBOX_CLOSE) {
4242
this.panelService.showHide();
43-
} else if (item.id === PANEL_TOOLBOX_RESIZE.id) {
43+
} else if (item.id === PANEL_TOOLBOX_RESIZE) {
4444
this.panelService.maximizeRestore();
4545
}
4646
this.emit(PanelEvent.onToolbarClick, e, item);

src/controller/problems.tsx

+11-6
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
StatusBarService,
1010
} from 'mo/services';
1111
import { singleton, container } from 'tsyringe';
12-
import { STATUS_PROBLEMS, PANEL_PROBLEMS } from 'mo/model/problems';
12+
import { builtInPanelProblems, builtInStatusProblems } from 'mo/model/problems';
1313
export interface IProblemsController {
1414
onClick?: (e: React.MouseEvent, item: IStatusBarItem) => void;
1515
}
@@ -19,20 +19,22 @@ export class ProblemsController
1919
implements IProblemsController {
2020
private readonly panelService: IPanelService;
2121
private readonly statusBarService: IStatusBarService;
22+
2223
constructor() {
2324
super();
2425
this.panelService = container.resolve(PanelService);
2526
this.statusBarService = container.resolve(StatusBarService);
2627
this.init();
2728
}
29+
2830
private showHideProblems() {
2931
const { current, hidden } = this.panelService.getState();
3032
if (hidden) {
3133
this.panelService.showHide();
32-
this.panelService.open(PANEL_PROBLEMS);
34+
this.panelService.open(builtInPanelProblems());
3335
} else {
34-
if (current?.id !== PANEL_PROBLEMS.id) {
35-
this.panelService.open(PANEL_PROBLEMS);
36+
if (current?.id !== builtInPanelProblems().id) {
37+
this.panelService.open(builtInPanelProblems());
3638
} else {
3739
this.panelService.showHide();
3840
}
@@ -42,12 +44,15 @@ export class ProblemsController
4244
public onClick = (e: React.MouseEvent, item: IStatusBarItem) => {
4345
this.showHideProblems();
4446
};
47+
4548
private init() {
4649
this.statusBarService.appendLeftItem(
47-
Object.assign(STATUS_PROBLEMS, {
50+
Object.assign(builtInStatusProblems(), {
4851
onClick: this.onClick,
4952
})
5053
);
51-
this.panelService.add(PANEL_PROBLEMS);
54+
this.panelService.add(builtInPanelProblems());
5255
}
5356
}
57+
58+
container.resolve(ProblemsController);

src/controller/search/search.tsx

+6-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
SEARCH_PRESERVE_CASE_COMMAND_ID,
1414
SEARCH_REPLACE_ALL_COMMAND_ID,
1515
SEARCH_ACTIVITY_ITEM,
16+
builtInSearchActivityItem,
1617
} from 'mo/model/workbench/search';
1718
import {
1819
ActivityBarService,
@@ -97,10 +98,10 @@ export class SearchController extends Controller implements ISearchController {
9798

9899
this.sidebarService.push(searchSidePane);
99100

100-
this.activityBarService.addBar(SEARCH_ACTIVITY_ITEM);
101+
this.activityBarService.addBar(builtInSearchActivityItem());
101102

102103
this.activityBarService.onSelect((e, item: IActivityBarItem) => {
103-
if (item.id === SEARCH_ACTIVITY_ITEM.id) {
104+
if (item.id === SEARCH_ACTIVITY_ITEM) {
104105
this.sidebarService.setState({
105106
current: searchSidePane.id,
106107
});
@@ -184,3 +185,6 @@ export class SearchController extends Controller implements ISearchController {
184185
return this.searchService.getSearchIndex(text, queryVal);
185186
};
186187
}
188+
189+
// Register a singleton
190+
container.resolve(SearchController);

0 commit comments

Comments
 (0)