Skip to content

Commit

Permalink
refactor: improve the Settings (#364)
Browse files Browse the repository at this point in the history
* refactor: rename the initial to initialize

* refactor: remove the useless code

* build: add @types/lodash into dependencies

* feat: add the built-in editorOption

* refactor: update built-in locales

* refactor: update built-in colorTheme

* fix(menubar): remove the optional for data property

* refactor: remove the example code for Settings

* refactor: improve the settingService

* test: add unit tests for the SettingsService

* refactor: remove useless await/async

* build: move the @types/lodash to devDependencies
  • Loading branch information
wewoor authored Aug 26, 2021
1 parent 91c7b3c commit 133153f
Show file tree
Hide file tree
Showing 17 changed files with 336 additions and 241 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^11.2.5",
"@types/jest": "^26.0.0",
"@types/lodash": "^4.14.172",
"@typescript-eslint/eslint-plugin": "^3.1.0",
"@typescript-eslint/parser": "^3.1.0",
"babel-loader": "^8.2.2",
Expand Down
41 changes: 16 additions & 25 deletions src/controller/settings.ts
Original file line number Diff line number Diff line change
@@ -1,60 +1,51 @@
import 'reflect-metadata';
import { container, singleton } from 'tsyringe';
import { Controller } from 'mo/react/controller';
import { debounce } from 'lodash';

import {
EditorService,
IEditorService,
IPanelService,
ISettingsService,
PanelService,
SettingsService,
} from 'mo/services';
import {
SettingsEvent,
BuiltInSettingsTab,
initialEditorSetting,
initialWorkbenchSetting,
} from 'mo/model/settings';
import { SettingsEvent, BuiltInSettingsTab } from 'mo/model/settings';

export interface ISettingsController {}

@singleton()
export class SettingsController
extends Controller
implements ISettingsController {
private readonly panelService: IPanelService;
private readonly editorService: IEditorService;
private readonly settingsService: ISettingsService;

constructor() {
super();
this.panelService = container.resolve(PanelService);
this.editorService = container.resolve(EditorService);
this.settingsService = container.resolve(SettingsService);

this.initial();
this.initialize();
}

private initial() {
/**
* Delay the each Settings change event 600 milliseconds,
* and then call the `update` and `emit` functions;
*/
private onChangeSettings = debounce((args) => {
this.settingsService.update(args);
this.emit(SettingsEvent.OnChange, args);
}, 600);

private initialize() {
this.editorService.onUpdateTab((tab) => {
if (tab.id === BuiltInSettingsTab.id) {
this.emit(SettingsEvent.OnChange, tab);
const config = this.settingsService.normalizeFlatObject(
const settingsValue = this.settingsService.normalizeFlatObject(
tab.data?.value || ''
);
config.editor = { ...initialEditorSetting, ...config.editor };
config.workbench = {
...initialWorkbenchSetting,
...config.workbench,
};
this.settingsService.update(config);
this.onChangeSettings(settingsValue);
}
});
}

public readonly onClick = (event: React.MouseEvent) => {
console.log('onClick:', this.panelService);
};
}

// Register singleton
Expand Down
22 changes: 15 additions & 7 deletions src/i18n/localeService.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {
builtInLocales,
defaultZhCn,
BuiltInLocales,
BuiltInZhCN,
ILocale,
LocalizationEvent,
} from 'mo/i18n/localization';
Expand All @@ -22,7 +22,7 @@ export interface ILocaleService {
/**
* Get the current locale language
*/
getCurrentLocale(): ILocale | undefined;
getCurrentLocale(): ILocale;
/**
* Get All locale languages
*/
Expand All @@ -32,6 +32,10 @@ export interface ILocaleService {
* @param id
*/
getLocale(id: string): ILocale | undefined;
/**
* Get the default locale
*/
getDefaultLocale(): ILocale;
/**
* Append multiple local languages
* @param locales
Expand Down Expand Up @@ -63,7 +67,11 @@ export class LocaleService extends Component implements ILocaleService {

constructor() {
super();
this.initialize(builtInLocales, defaultZhCn.id);
this.initialize(BuiltInLocales, BuiltInZhCN.id);
}

public getDefaultLocale(): ILocale {
return Object.assign({}, BuiltInZhCN);
}

public getLocales(): ILocale[] {
Expand All @@ -77,8 +85,8 @@ export class LocaleService extends Component implements ILocaleService {
}
}

public getCurrentLocale(): ILocale | undefined {
return this._current;
public getCurrentLocale(): ILocale {
return Object.assign({}, this._current || this.getDefaultLocale());
}

public getLocale(id: string): ILocale | undefined {
Expand All @@ -89,7 +97,7 @@ export class LocaleService extends Component implements ILocaleService {
const locale = this._locales.get(id);
if (locale !== undefined) {
if (this._current && this._current.id === locale.id) {
this._current = defaultZhCn;
this._current = BuiltInZhCN;
}
this._locales.delete(id);
}
Expand Down
10 changes: 5 additions & 5 deletions src/i18n/localization.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import defaultEN from './source/en';
export const defaultZhCn = require('./source/zh-CN.json');
import BuiltInEN from './source/en';

export type LocaleSourceIdType = keyof typeof defaultEN.source;

export const builtInLocales = [defaultEN, defaultZhCn];
export const BuiltInZhCN = require('./source/zh-CN.json');
export { default as BuiltInEN } from './source/en';
export type LocaleSourceIdType = keyof typeof BuiltInEN.source;
export const BuiltInLocales = [BuiltInZhCN, BuiltInEN];

/**
* The Localization configuration event definition
Expand Down
44 changes: 14 additions & 30 deletions src/model/settings.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
import { editor as MonacoEditor } from 'monaco-editor';

export interface IConfiguration {
[key: string]: any;
}

export type IEditorSettings = MonacoEditor.IEditorOptions &
MonacoEditor.IGlobalEditorOptions;
import { IEditorOptions } from './workbench';

/**
* The Settings configuration event definition
Expand All @@ -17,16 +10,6 @@ export enum SettingsEvent {
OnChange = 'settings.onchange',
}

export const initialWorkbenchSetting = {
colorTheme: 'Default Dark+',
};

export const initialEditorSetting: IEditorSettings = {
renderWhitespace: 'none',
tabSize: 4,
fontSize: 14,
};

export const BuiltInSettingsTab = {
id: 'Settings',
name: 'settings.json',
Expand All @@ -36,21 +19,22 @@ export const BuiltInSettingsTab = {
},
};

export type IWorkbenchSettings = typeof initialWorkbenchSetting;

export interface ISettings extends IConfiguration {
workbench: IWorkbenchSettings;
editor: IEditorSettings;
export interface ISettings {
colorTheme?: string;
editor?: IEditorOptions;
locale?: string;
[index: string]: any;
}

export class SettingsModel implements ISettings {
workbench: IWorkbenchSettings;
editor: IEditorSettings;
colorTheme: string;
editor: IEditorOptions;
locale: string;

constructor(
workbench: IWorkbenchSettings = { ...initialWorkbenchSetting },
editor: IEditorSettings = { ...initialEditorSetting }
) {
this.workbench = workbench;
constructor(colorTheme: string, editor: IEditorOptions, locale: string) {
this.colorTheme = colorTheme;
this.editor = editor;
this.locale = locale;
}
[key: string]: any;
}
26 changes: 24 additions & 2 deletions src/model/workbench/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ITabsProps } from 'mo/components/tabs';
import { IMenuItemProps } from 'mo/components/menu';
import { IBreadcrumbItemProps } from 'mo/components/breadcrumb';
import { localize } from 'mo/i18n/localize';
import { editor as MonacoEditor } from 'monaco-editor';

export enum EditorEvent {
OnCloseTab = 'editor.closeTab',
Expand All @@ -22,10 +23,18 @@ interface BuiltInEditorTabDataType {
path?: string;
value?: string;
modified?: boolean;

[key: string]: any;
}

export type IEditorOptions = MonacoEditor.IEditorOptions &
MonacoEditor.IGlobalEditorOptions;

export const BuiltInEditorOptions: IEditorOptions = {
renderWhitespace: 'none',
tabSize: 4,
fontSize: 12,
};

export interface IEditorActionsProps extends IMenuItemProps {
id: string;
/**
Expand Down Expand Up @@ -56,8 +65,18 @@ export interface IEditor {
* Current editor group
*/
current?: IEditorGroup | null;
/**
* Editor Groups
*/
groups?: IEditorGroup[];
/**
* The welcome page of editor bench
*/
entry?: React.ReactNode;
/**
* Built-in editor options, there is main apply it to monaco-editor
*/
editorOptions?: IEditorOptions;
}

export const EDITOR_MENU_CLOSE_TO_RIGHT = 'editor.closeToRight';
Expand Down Expand Up @@ -146,14 +165,17 @@ export class EditorModel implements IEditor {
public current: IEditorGroup | null;
public groups: IEditorGroup[];
public entry: React.ReactNode;
public editorOptions: IEditorOptions;

constructor(
current: IEditorGroup | null = null,
groups: IEditorGroup[] = [],
entry: React.ReactNode
entry: React.ReactNode,
editorOptions: IEditorOptions = BuiltInEditorOptions
) {
this.current = current;
this.groups = groups;
this.entry = entry;
this.editorOptions = editorOptions;
}
}
2 changes: 1 addition & 1 deletion src/model/workbench/menuBar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export interface IMenuBarItem {
render?: () => React.ReactNode | JSX.Element;
}
export interface IMenuBar {
data?: IMenuBarItem[];
data: IMenuBarItem[];
}

export const MENU_FILE_OPEN = 'openFile';
Expand Down
10 changes: 10 additions & 0 deletions src/services/__tests__/__snapshots__/settingsService.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Test the SettingsService Convert invalid object to JSON string 1`] = `
"SettingsService.toJSONString error: TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Object'
| property 'b' -> object with constructor 'Object'
--- property 'a' closes the circle"
`;

exports[`Test the SettingsService Normalize a invalid FlatObject 1`] = `"SettingsService.normalizeFlatJSONObject error: SyntaxError: Unexpected token ' in JSON at position 14"`;
20 changes: 10 additions & 10 deletions src/services/__tests__/colorThemeService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { cleanup } from '@testing-library/react';
import 'reflect-metadata';
import { container } from 'tsyringe';
import {
BUILT_IN_THEME,
BuiltInColorTheme,
ColorThemeService,
DEFAULT_THEME_CLASS_NAME,
} from '../theme/colorThemeService';
Expand All @@ -23,15 +23,15 @@ describe('The Color Theme Service', () => {
});

test('Should when initialize', () => {
const service = new ColorThemeService([], BUILT_IN_THEME);
expect(service.getColorTheme()).toEqual(BUILT_IN_THEME);
const service = new ColorThemeService();
expect(service.getColorTheme()).toEqual(BuiltInColorTheme);
});

test('Should have default theme', () => {
const currentColorTheme = colorThemeService.getColorTheme();
const colorThemes = colorThemeService.getThemes();

expect(currentColorTheme.id).toBe(BUILT_IN_THEME.id);
expect(currentColorTheme.id).toBe(BuiltInColorTheme.id);
expect(colorThemes).toHaveLength(1);
});

Expand Down Expand Up @@ -95,13 +95,13 @@ describe('The Color Theme Service', () => {

test('Should update specific theme', () => {
colorThemeService.updateTheme({
...BUILT_IN_THEME,
...BuiltInColorTheme,
label: 'Dark Test',
});

expect(colorThemeService.getThemeById(BUILT_IN_THEME.id)?.label).toBe(
'Dark Test'
);
expect(
colorThemeService.getThemeById(BuiltInColorTheme.id)?.label
).toBe('Dark Test');
});

test('Should reload current theme if update the theme', () => {
Expand All @@ -110,7 +110,7 @@ describe('The Color Theme Service', () => {
);
expect(styleDom?.innerHTML).toContain('--editor-background: #1E1E1E');
colorThemeService.updateTheme({
...BUILT_IN_THEME,
...BuiltInColorTheme,
label: 'Dark Test',
colors: {
'editor.background': '#000',
Expand All @@ -124,7 +124,7 @@ describe('The Color Theme Service', () => {
const originalError = console.error;
console.error = jest.fn();
colorThemeService.updateTheme({
...BUILT_IN_THEME,
...BuiltInColorTheme,
label: 'Dark Test',
id: '',
});
Expand Down
Loading

0 comments on commit 133153f

Please sign in to comment.