Skip to content

Commit 49021ff

Browse files
authored
feat: add diff viewer component (#101)
1 parent a4d67b7 commit 49021ff

26 files changed

Lines changed: 1322 additions & 567 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,4 @@ generated-parser
116116
.husky
117117

118118
scripts/utils/_upload.js
119+
packages/startup/src/diff-viewer/remote.ts

jest.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ module.exports = {
1313
moduleNameMapper: {
1414
'^@codeblitzjs/ide-core-(?!browserfs)(.*?)$': '<rootDir>/packages/$1/src',
1515
'^@codeblitzjs/ide-core$': '<rootDir>/packages/core/src',
16-
'\\.(css|less)$': '<rootDir>/mocks/styleMock.js',
16+
'\\.(css|less)$': '<rootDir>/scripts/jest/mocks/styleMock.js',
1717
},
1818
rootDir: __dirname,
1919
testMatch: ['<rootDir>/packages/**/__tests__/**/*@(test|spec).[jt]s?(x)'],

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"description": "codeblitzjs",
99
"main": "index.js",
1010
"engines": {
11-
"opensumi": "3.1.4-next-1719380894.0"
11+
"opensumi": "3.1.5-next-1721574303.0"
1212
},
1313
"scripts": {
1414
"prepare": "husky install",
@@ -19,6 +19,7 @@
1919
"generate": "node scripts/generate",
2020
"editor": "INTEGRATION=editor npm run dev",
2121
"fs": "INTEGRATION=filesystem npm run dev",
22+
"diff-viewer": "INTEGRATION=diff-viewer npm run dev",
2223
"build": "node scripts/build",
2324
"build:all": "yarn run bundle && yarn run generate && yarn run build",
2425
"bundle": "node scripts/bundle",

packages/cli/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010
"opensumi codeblitzjs"
1111
],
1212
"engines": {
13-
"opensumi": "3.1.4-next-1719380894.0",
13+
"opensumi": "3.1.5-next-1721574303.0",
1414
"node": ">=10.0.0"
1515
},
1616
"dependencies": {
1717
"@codeblitzjs/ide-common": "1.0.4",
18-
"@opensumi/ide-extension": "3.1.4-next-1719380894.0",
18+
"@opensumi/ide-extension": "3.1.5-next-1721574303.0",
1919
"async-retry": "^1.3.1",
2020
"await-event": "^2.1.0",
2121
"commander": "^7.2.0",

packages/core/package.json

Lines changed: 42 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -33,48 +33,48 @@
3333
"@codeblitzjs/ide-plugin": "1.0.4",
3434
"@codeblitzjs/ide-registry": "1.0.4",
3535
"@codeblitzjs/ide-sumi-core": "1.0.4",
36-
"@opensumi/ide-addons": "3.1.4-next-1719380894.0",
37-
"@opensumi/ide-ai-native": "3.1.4-next-1719380894.0",
38-
"@opensumi/ide-comments": "3.1.4-next-1719380894.0",
39-
"@opensumi/ide-core-browser": "3.1.4-next-1719380894.0",
40-
"@opensumi/ide-core-common": "3.1.4-next-1719380894.0",
41-
"@opensumi/ide-debug": "3.1.4-next-1719380894.0",
42-
"@opensumi/ide-decoration": "3.1.4-next-1719380894.0",
43-
"@opensumi/ide-design": "3.1.4-next-1719380894.0",
44-
"@opensumi/ide-editor": "3.1.4-next-1719380894.0",
45-
"@opensumi/ide-explorer": "3.1.4-next-1719380894.0",
46-
"@opensumi/ide-express-file-server": "3.1.4-next-1719380894.0",
47-
"@opensumi/ide-extension": "3.1.4-next-1719380894.0",
48-
"@opensumi/ide-extension-storage": "3.1.4-next-1719380894.0",
49-
"@opensumi/ide-file-scheme": "3.1.4-next-1719380894.0",
50-
"@opensumi/ide-file-service": "3.1.4-next-1719380894.0",
51-
"@opensumi/ide-file-tree-next": "3.1.4-next-1719380894.0",
52-
"@opensumi/ide-i18n": "3.1.4-next-1719380894.0",
53-
"@opensumi/ide-keymaps": "3.1.4-next-1719380894.0",
54-
"@opensumi/ide-logs": "3.1.4-next-1719380894.0",
55-
"@opensumi/ide-main-layout": "3.1.4-next-1719380894.0",
56-
"@opensumi/ide-markdown": "3.1.4-next-1719380894.0",
57-
"@opensumi/ide-markers": "3.1.4-next-1719380894.0",
58-
"@opensumi/ide-menu-bar": "3.1.4-next-1719380894.0",
59-
"@opensumi/ide-monaco": "3.1.4-next-1719380894.0",
60-
"@opensumi/ide-monaco-enhance": "3.1.4-next-1719380894.0",
61-
"@opensumi/ide-opened-editor": "3.1.4-next-1719380894.0",
62-
"@opensumi/ide-outline": "3.1.4-next-1719380894.0",
63-
"@opensumi/ide-output": "3.1.4-next-1719380894.0",
64-
"@opensumi/ide-overlay": "3.1.4-next-1719380894.0",
65-
"@opensumi/ide-preferences": "3.1.4-next-1719380894.0",
66-
"@opensumi/ide-quick-open": "3.1.4-next-1719380894.0",
67-
"@opensumi/ide-scm": "3.1.4-next-1719380894.0",
68-
"@opensumi/ide-search": "3.1.4-next-1719380894.0",
69-
"@opensumi/ide-status-bar": "3.1.4-next-1719380894.0",
70-
"@opensumi/ide-storage": "3.1.4-next-1719380894.0",
71-
"@opensumi/ide-testing": "3.1.4-next-1719380894.0",
72-
"@opensumi/ide-theme": "3.1.4-next-1719380894.0",
73-
"@opensumi/ide-toolbar": "3.1.4-next-1719380894.0",
74-
"@opensumi/ide-variable": "3.1.4-next-1719380894.0",
75-
"@opensumi/ide-webview": "3.1.4-next-1719380894.0",
76-
"@opensumi/ide-workspace": "3.1.4-next-1719380894.0",
77-
"@opensumi/ide-workspace-edit": "3.1.4-next-1719380894.0",
36+
"@opensumi/ide-addons": "3.1.5-next-1721574303.0",
37+
"@opensumi/ide-ai-native": "3.1.5-next-1721574303.0",
38+
"@opensumi/ide-comments": "3.1.5-next-1721574303.0",
39+
"@opensumi/ide-core-browser": "3.1.5-next-1721574303.0",
40+
"@opensumi/ide-core-common": "3.1.5-next-1721574303.0",
41+
"@opensumi/ide-debug": "3.1.5-next-1721574303.0",
42+
"@opensumi/ide-decoration": "3.1.5-next-1721574303.0",
43+
"@opensumi/ide-design": "3.1.5-next-1721574303.0",
44+
"@opensumi/ide-editor": "3.1.5-next-1721574303.0",
45+
"@opensumi/ide-explorer": "3.1.5-next-1721574303.0",
46+
"@opensumi/ide-express-file-server": "3.1.5-next-1721574303.0",
47+
"@opensumi/ide-extension": "3.1.5-next-1721574303.0",
48+
"@opensumi/ide-extension-storage": "3.1.5-next-1721574303.0",
49+
"@opensumi/ide-file-scheme": "3.1.5-next-1721574303.0",
50+
"@opensumi/ide-file-service": "3.1.5-next-1721574303.0",
51+
"@opensumi/ide-file-tree-next": "3.1.5-next-1721574303.0",
52+
"@opensumi/ide-i18n": "3.1.5-next-1721574303.0",
53+
"@opensumi/ide-keymaps": "3.1.5-next-1721574303.0",
54+
"@opensumi/ide-logs": "3.1.5-next-1721574303.0",
55+
"@opensumi/ide-main-layout": "3.1.5-next-1721574303.0",
56+
"@opensumi/ide-markdown": "3.1.5-next-1721574303.0",
57+
"@opensumi/ide-markers": "3.1.5-next-1721574303.0",
58+
"@opensumi/ide-menu-bar": "3.1.5-next-1721574303.0",
59+
"@opensumi/ide-monaco": "3.1.5-next-1721574303.0",
60+
"@opensumi/ide-monaco-enhance": "3.1.5-next-1721574303.0",
61+
"@opensumi/ide-opened-editor": "3.1.5-next-1721574303.0",
62+
"@opensumi/ide-outline": "3.1.5-next-1721574303.0",
63+
"@opensumi/ide-output": "3.1.5-next-1721574303.0",
64+
"@opensumi/ide-overlay": "3.1.5-next-1721574303.0",
65+
"@opensumi/ide-preferences": "3.1.5-next-1721574303.0",
66+
"@opensumi/ide-quick-open": "3.1.5-next-1721574303.0",
67+
"@opensumi/ide-scm": "3.1.5-next-1721574303.0",
68+
"@opensumi/ide-search": "3.1.5-next-1721574303.0",
69+
"@opensumi/ide-status-bar": "3.1.5-next-1721574303.0",
70+
"@opensumi/ide-storage": "3.1.5-next-1721574303.0",
71+
"@opensumi/ide-testing": "3.1.5-next-1721574303.0",
72+
"@opensumi/ide-theme": "3.1.5-next-1721574303.0",
73+
"@opensumi/ide-toolbar": "3.1.5-next-1721574303.0",
74+
"@opensumi/ide-variable": "3.1.5-next-1721574303.0",
75+
"@opensumi/ide-webview": "3.1.5-next-1721574303.0",
76+
"@opensumi/ide-workspace": "3.1.5-next-1721574303.0",
77+
"@opensumi/ide-workspace-edit": "3.1.5-next-1721574303.0",
7878
"@opensumi/textmate-languages": "^2.7.0",
7979
"tslib": "^2.2.0"
8080
},

packages/core/src/api/renderApp.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { getDebugLogger, IReporterService, localize } from '@opensumi/ide-core-c
33
import React, { useEffect, useMemo, useRef, useState } from 'react';
44
import { createRoot } from 'react-dom/client';
55
import { useConstant } from '../core/hooks';
6+
import { IPropsService, PropsServiceImpl } from '../core/props.service';
67
import { Root } from '../core/Root';
78
import styles from '../core/style.module.less';
89
import { LandingProps, RootProps } from '../core/types';
@@ -61,9 +62,9 @@ export const AppRenderer: React.FC<IAppRendererProps> = ({ onLoad, Landing, ...o
6162
const app = useConstant(() => createApp(opts));
6263
const themeType = useConstant(() => app.currentThemeType);
6364
const appElementRef = useRef<React.FC | null>(null);
65+
const propsService = useConstant(() => new PropsServiceImpl<IAppRendererProps>());
66+
propsService.props = opts;
6467

65-
// 确保回调始终为最新
66-
// TODO: 用 PropsService
6768
const runtimeConfig: RuntimeConfig = app.injector.get(RuntimeConfig);
6869
runtimeConfig.workspace = opts.runtimeConfig.workspace;
6970

@@ -72,6 +73,13 @@ export const AppRenderer: React.FC<IAppRendererProps> = ({ onLoad, Landing, ...o
7273
error?: RootProps['error'];
7374
}>(() => ({ status: 'loading' }));
7475

76+
useMemo(() => {
77+
app.injector.addProviders({
78+
token: IPropsService,
79+
useValue: propsService,
80+
});
81+
}, []);
82+
7583
useEffect(() => {
7684
app
7785
.start((appElement) => {
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import { deletionLogPath } from '@codeblitzjs/ide-browserfs/lib/backend/OverlayFS';
2+
import {
3+
FILES_DEFAULTS,
4+
ModuleConstructor,
5+
randomString,
6+
SlotLocation,
7+
SlotRenderer,
8+
} from '@opensumi/ide-core-browser';
9+
import merge from 'lodash/merge';
10+
import React from 'react';
11+
import { IDiffViewerProps } from '../core/diff-viewer';
12+
import { DiffViewerModule } from '../core/diff-viewer/module';
13+
import { BoxPanel, SplitPanel } from '../editor';
14+
import { Injector } from '../modules/opensumi__common-di';
15+
import { AppRenderer, IAppRendererProps } from './renderApp';
16+
17+
export const defaultLayoutConfig = {
18+
[SlotLocation.action]: {
19+
modules: [''],
20+
},
21+
[SlotLocation.main]: {
22+
modules: ['@opensumi/ide-editor'],
23+
},
24+
[SlotLocation.extra]: {
25+
modules: ['breadcrumb-menu'],
26+
},
27+
};
28+
29+
export function DiffViewerLayoutComponent(): React.ReactElement {
30+
return (
31+
<BoxPanel direction='top-to-bottom'>
32+
<SlotRenderer slot='top' />
33+
<SplitPanel overflow='hidden' id='main-horizontal' flex={1}>
34+
<SlotRenderer slot='left' defaultSize={310} minResize={204} minSize={49} />
35+
<SplitPanel id='main-vertical' minResize={300} flexGrow={1} direction='top-to-bottom'>
36+
<SlotRenderer flex={2} flexGrow={1} minResize={200} slot='main' />
37+
<SlotRenderer flex={1} minResize={160} slot='bottom' />
38+
</SplitPanel>
39+
</SplitPanel>
40+
<SlotRenderer slot='statusBar' />
41+
</BoxPanel>
42+
);
43+
}
44+
45+
export const DiffViewerRenderer = (_props: IDiffViewerProps) => {
46+
const props = merge({
47+
appConfig: {},
48+
}, _props) as IAppRendererProps;
49+
50+
if (!props.appConfig.injector) {
51+
props.appConfig.injector = new Injector();
52+
}
53+
54+
const injector = props.appConfig.injector;
55+
56+
injector.addProviders({
57+
token: IDiffViewerProps,
58+
useValue: props,
59+
});
60+
61+
const appConfig = props.appConfig;
62+
63+
const appModules: ModuleConstructor[] = appConfig?.modules || [];
64+
if (!appModules.includes(DiffViewerModule)) {
65+
appModules.unshift(DiffViewerModule);
66+
}
67+
delete appConfig?.modules;
68+
69+
const workspaceDir = appConfig?.workspaceDir || 'workspace-' + randomString(8);
70+
delete (appConfig as Partial<IAppRendererProps['appConfig']>)?.workspaceDir;
71+
72+
const layoutConfig = appConfig?.layoutConfig || defaultLayoutConfig;
73+
delete appConfig?.layoutConfig;
74+
75+
const layoutComponent = appConfig?.layoutComponent || DiffViewerLayoutComponent;
76+
delete appConfig?.layoutComponent;
77+
78+
const diffViewerAppConfig: IAppRendererProps = merge<IAppRendererProps, Partial<IAppRendererProps>>({
79+
appConfig: {
80+
modules: appModules,
81+
workspaceDir,
82+
layoutComponent,
83+
layoutConfig,
84+
disableRestoreEditorGroupState: true,
85+
defaultPreferences: {
86+
'general.theme': 'opensumi-design-light-theme',
87+
'editor.minimap': false,
88+
'ai.native.inlineDiff.preview.mode': 'inlineLive',
89+
'editor.autoSave': 'afterDelay',
90+
'application.confirmExit': 'never',
91+
'editor.guides.bracketPairs': false,
92+
'editor.quickSuggestionsDelay': 10,
93+
'editor.previewMode': false,
94+
'editor.autoSaveDelay': 1000, // one second
95+
'editor.fixedOverflowWidgets': true, // widget editor 默认改为 fixed
96+
'editor.unicodeHighlight.ambiguousCharacters': false,
97+
'editor.preventScrollAfterFocused': true,
98+
'files.exclude': {
99+
...FILES_DEFAULTS.filesExclude,
100+
// browserfs OverlayFS 用来记录删除的文件
101+
[`**${deletionLogPath}`]: true,
102+
},
103+
},
104+
},
105+
runtimeConfig: ({
106+
aiNative: {
107+
enable: true,
108+
capabilities: {
109+
supportsInlineChat: true,
110+
},
111+
},
112+
startupEditor: 'none',
113+
workspace: {
114+
filesystem: {
115+
fs: 'InMemory',
116+
options: {},
117+
},
118+
},
119+
}),
120+
}, props);
121+
122+
return (
123+
<AppRenderer
124+
{...diffViewerAppConfig}
125+
/>
126+
);
127+
};

packages/core/src/api/types.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
/// <reference path="../../typings/index.d.ts" />
22

3-
import { IAppOpts, RuntimeConfig, ClientApp } from '@codeblitzjs/ide-sumi-core';
4-
import { IAppRenderer } from '@opensumi/ide-core-browser';
53
import { IPluginConfig } from '@codeblitzjs/ide-plugin';
6-
import { ThemeType } from '@opensumi/ide-theme';
4+
import { ClientApp, IAppOpts, RuntimeConfig } from '@codeblitzjs/ide-sumi-core';
75
import { Injector } from '@opensumi/di';
6+
import { IAppRenderer } from '@opensumi/ide-core-browser';
7+
import { ThemeType } from '@opensumi/ide-theme';
88

99
export type { IPluginAPI, IPluginModule } from '@codeblitzjs/ide-plugin';
1010

11-
export type IAppConfig = Partial<IAppOpts> & {
11+
export interface IAppConfig extends Partial<IAppOpts> {
1212
/**
1313
* 工作空间目录,最好确保不同项目名称不同,如 group/repository 的形式,工作空间目录会挂载到 /workspace 根目录下
1414
*/
1515
workspaceDir: string;
16-
} & {
1716
/**
1817
* 插件配置
1918
*/
@@ -23,7 +22,7 @@ export type IAppConfig = Partial<IAppOpts> & {
2322
* extensionOSSPath/publisher.name-version
2423
*/
2524
extensionOSSPath?: string;
26-
};
25+
}
2726

2827
export interface IConfig {
2928
/**

0 commit comments

Comments
 (0)