Skip to content

Commit 03e36b2

Browse files
author
winjo
authored
chore: add editor save and update example (#182)
1 parent 0cff95e commit 03e36b2

2 files changed

Lines changed: 124 additions & 49 deletions

File tree

packages/startup/src/provider/index.tsx

Lines changed: 66 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { AppProvider, CodeEditor, DiffEditor } from '@codeblitzjs/ide-core';
22
import React, { useEffect, useState } from 'react';
33
import { createRoot } from 'react-dom/client';
44
import '@codeblitzjs/ide-core/languages';
5-
import { SampleModule, diffsDeferred } from './module'
5+
import { SampleModule, diffService } from './module'
66
import '../index.css';
77
import './index.css'
88

@@ -21,54 +21,76 @@ const App = () => {
2121
newFileContent: 'const add = (x, y) => {\n return x + y + 1\n}'
2222
}]
2323
setDiffs(diffs)
24-
diffsDeferred.resolve(diffs)
24+
diffService.updateData(diffs)
2525
}, 1000)
26+
27+
return () => {
28+
diffService.clear()
29+
}
2630
}, [])
2731

28-
if (!diffs) return null
32+
const update = () => {
33+
const diffs = [{
34+
filePath: 'a1.js',
35+
oldFileContent: 'const add = (x, y) => {\n return x + y\n}',
36+
newFileContent: 'const add = (x, y) => {\n return x + y + 2\n}'
37+
}, {
38+
filePath: 'a2.js',
39+
oldFileContent: 'const add = (x, y) => {\n return x + y\n}',
40+
newFileContent: 'const sub = (x, y) => {\n return x - y\n}'
41+
}]
42+
setDiffs(diffs)
43+
diffService.updateData(diffs)
44+
}
2945

3046
return (
31-
<AppProvider
32-
appConfig={{
33-
workspaceDir: 'my-workspace',
34-
layoutConfig: {},
35-
modules: [SampleModule],
36-
}}
37-
runtimeConfig={{
38-
biz: 'startup',
39-
}}
40-
>
41-
{diffs.map(({ filePath, oldFileContent, newFileContent }) => {
42-
if (!oldFileContent) {
43-
return (
44-
<CodeEditor
45-
key={filePath}
46-
uri={`sample://new/${filePath}`}
47-
style={{ width: 1000, height: 300, marginBottom: 16 }}
48-
editorOptions={{
49-
scrollbar: {
50-
alwaysConsumeMouseWheel: false
51-
}
52-
}}
53-
/>
54-
)
55-
} else {
56-
return (
57-
<DiffEditor
58-
key={filePath}
59-
originalUri={`sample://old/${filePath}`}
60-
modifiedUri={`sample://new/${filePath}`}
61-
editorOptions={{
62-
scrollbar: {
63-
alwaysConsumeMouseWheel: false
64-
}
65-
}}
66-
style={{ width: 1000, height: 300 }}
67-
/>
68-
)
69-
}
70-
})}
71-
</AppProvider>
47+
<>
48+
<button onClick={update} style={{ marginBottom: 16 }}>更新</button>
49+
<AppProvider
50+
appConfig={{
51+
workspaceDir: 'my-workspace',
52+
modules: [SampleModule],
53+
defaultPreferences: {
54+
'editor.autoSave': 'afterDelay',
55+
'editor.autoSaveDelay': 1000
56+
}
57+
}}
58+
runtimeConfig={{
59+
biz: 'startup',
60+
}}
61+
>
62+
{diffs.map(({ filePath, oldFileContent, newFileContent }) => {
63+
if (!oldFileContent) {
64+
return (
65+
<CodeEditor
66+
key={filePath}
67+
uri={`sample://new/${filePath}`}
68+
style={{ width: 1000, height: 300, marginBottom: 16 }}
69+
editorOptions={{
70+
scrollbar: {
71+
alwaysConsumeMouseWheel: false
72+
}
73+
}}
74+
/>
75+
)
76+
} else {
77+
return (
78+
<DiffEditor
79+
key={filePath}
80+
originalUri={`sample://old/${filePath}`}
81+
modifiedUri={`sample://new/${filePath}`}
82+
editorOptions={{
83+
scrollbar: {
84+
alwaysConsumeMouseWheel: false
85+
}
86+
}}
87+
style={{ width: 1000, height: 300, marginBottom: 16 }}
88+
/>
89+
)
90+
}
91+
})}
92+
</AppProvider>
93+
</>
7294
)
7395
};
7496

packages/startup/src/provider/module.ts

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,67 @@
11
import { Autowired, Injectable, Provider } from '@opensumi/di';
22
import { BrowserModule } from '@opensumi/ide-core-browser';
33
import { IEditorDocumentModelContentProvider, BrowserEditorContribution, IEditorDocumentModelContentRegistry } from '@opensumi/ide-editor/lib/browser'
4-
import { URI, Emitter, Event, Domain, Deferred } from '@opensumi/ide-core-common'
4+
import { URI, Emitter, Event, Domain, IEditorDocumentChange, IEditorDocumentModelSaveResult, SaveTaskResponseState } from '@opensumi/ide-core-common'
55

6-
export const diffsDeferred = new Deferred<{filePath: string, oldFileContent: string | null, newFileContent: string }[]>()
6+
export interface IDiffData {
7+
filePath: string;
8+
oldFileContent: string | null;
9+
newFileContent: string;
10+
}
11+
12+
class DiffService {
13+
#data: IDiffData[] | null = null
14+
#dataEmitter = new Emitter<URI[]>()
15+
onDataChange = this.#dataEmitter.event;
16+
17+
get data() {
18+
return this.#data;
19+
}
20+
updateData(data: IDiffData[]) {
21+
const lastData = this.#data
22+
this.#data = data
23+
const lastDataMap: Record<string, IDiffData> = lastData?.reduce((obj, item) => {
24+
obj[item.filePath] = item
25+
return obj
26+
}, {}) || {}
27+
const uris: URI[] = []
28+
data.forEach(item => {
29+
const lastItem = lastDataMap?.[item.filePath]
30+
if (!lastItem) return
31+
if (item.oldFileContent !== lastItem.oldFileContent) {
32+
uris.push(new URI(`sample://old/${item.filePath}`))
33+
}
34+
if (item.newFileContent !== lastItem.newFileContent) {
35+
uris.push(new URI(`sample://new/${item.filePath}`))
36+
}
37+
})
38+
this.#dataEmitter.fire(uris)
39+
}
40+
41+
clear() {
42+
this.#data = null
43+
}
44+
}
45+
46+
export const diffService = new DiffService()
747

848
@Injectable()
949
export class SampleSchemeDocumentProvider implements IEditorDocumentModelContentProvider {
50+
private _onDidChangeContent: Emitter<URI> = new Emitter();
51+
onDidChangeContent: Event<URI> = this._onDidChangeContent.event;
52+
53+
constructor() {
54+
diffService.onDataChange((uris) => {
55+
uris.forEach(uri => this._onDidChangeContent.fire(uri))
56+
})
57+
}
58+
1059
handlesScheme(scheme: string) {
1160
return scheme === 'sample';
1261
}
1362

1463
async provideEditorDocumentModelContent(uri: URI): Promise<string> {
15-
const diffs = await diffsDeferred.promise
64+
const diffs = diffService.data || []
1665
const diff = diffs.find(item => item.filePath === uri.codeUri.path.slice(1))
1766
if (!diff) return ''
1867
if (uri.authority === 'new') return diff.newFileContent
@@ -23,8 +72,12 @@ export class SampleSchemeDocumentProvider implements IEditorDocumentModelContent
2372
return false;
2473
}
2574

26-
private _onDidChangeContent: Emitter<URI> = new Emitter();
27-
onDidChangeContent: Event<URI> = this._onDidChangeContent.event;
75+
async saveDocumentModel(uri: URI, content: string, baseContent: string, changes: IEditorDocumentChange[]): Promise<IEditorDocumentModelSaveResult> {
76+
console.log(uri, content, baseContent, changes)
77+
return {
78+
state: SaveTaskResponseState.SUCCESS,
79+
}
80+
}
2881
}
2982

3083
@Domain(BrowserEditorContribution)

0 commit comments

Comments
 (0)