-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
208 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import React, { useContext, useEffect, useMemo, useRef, MutableRefObject } from 'react'; | ||
|
||
import * as path from 'path' | ||
import { URI, useInjectable } from '@opensumi/ide-core-browser'; | ||
import { ConfigProvider, AppConfig } from '@opensumi/ide-core-browser/lib/react-providers/config-provider' | ||
import { EditorCollectionService, IDiffEditor, IEditorDocumentModelRef } from '@opensumi/ide-editor/lib/common' | ||
import { IEditorDocumentModelService } from '@opensumi/ide-editor/lib/browser/doc-model/types' | ||
import { AppContext } from './context' | ||
import { useMemorizeFn } from '../hooks' | ||
import { parseUri } from './util' | ||
|
||
const noop = () => {} | ||
|
||
export interface ICodeEditorProps extends React.HTMLAttributes<HTMLDivElement> { | ||
originalUri: URI | string; | ||
|
||
modifiedUri: URI | string; | ||
|
||
editorOptions?: any; | ||
|
||
onEditorCreate?: (editor: IDiffEditor) => void; | ||
} | ||
|
||
export const DiffEditorComponent = ({ originalUri, modifiedUri, editorOptions, onEditorCreate, ...props }: ICodeEditorProps) => { | ||
const editorCollectionService: EditorCollectionService = useInjectable(EditorCollectionService); | ||
const documentService: IEditorDocumentModelService = useInjectable(IEditorDocumentModelService); | ||
const appConfig: AppConfig = useInjectable(AppConfig); | ||
|
||
const containerRef = React.useRef<HTMLDivElement | null>(null); | ||
const editorRef = useRef<IDiffEditor>() | ||
const unmountRef = useRef(false); | ||
const onEditorCreateMemorizeFn = useMemorizeFn(onEditorCreate || noop) | ||
|
||
const originalUriStr = useMemo(() => parseUri(originalUri, appConfig.workspaceDir), [originalUri]) | ||
const originalFetchingUriRef = useRef<string>(''); | ||
const originalDocumentModelRef = useRef<IEditorDocumentModelRef>(); | ||
|
||
const modifiedUriStr = useMemo(() => parseUri(modifiedUri, appConfig.workspaceDir), [modifiedUri]) | ||
const modifiedFetchingUriRef = useRef<string>(''); | ||
const modifiedDocumentModelRef = useRef<IEditorDocumentModelRef>(); | ||
|
||
const openDocumentModel = () => { | ||
if (editorRef.current && originalDocumentModelRef.current && modifiedDocumentModelRef.current) { | ||
editorRef.current.compare(originalDocumentModelRef.current, modifiedDocumentModelRef.current) | ||
} | ||
} | ||
|
||
React.useEffect(() => { | ||
if (containerRef.current) { | ||
editorRef.current?.dispose(); | ||
editorRef.current = editorCollectionService.createDiffEditor(containerRef.current, { | ||
automaticLayout: true, | ||
...editorOptions, | ||
}); | ||
onEditorCreateMemorizeFn(editorRef.current) | ||
openDocumentModel() | ||
} | ||
return () => { | ||
unmountRef.current = true; | ||
editorRef.current?.dispose() | ||
originalDocumentModelRef.current?.dispose() | ||
modifiedDocumentModelRef.current?.dispose() | ||
}; | ||
}, []); | ||
|
||
useEffect(() => { | ||
const createModelReference = ( | ||
fetchingUriRef: MutableRefObject<string>, | ||
uriStr: string, | ||
documentModelRef: MutableRefObject<IEditorDocumentModelRef | undefined> | ||
) => { | ||
if (fetchingUriRef.current !== uriStr) { | ||
fetchingUriRef.current = uriStr | ||
documentService.createModelReference(new URI(uriStr), 'diff-editor-react-component').then((ref) => { | ||
if (documentModelRef.current) { | ||
documentModelRef.current.dispose(); | ||
} | ||
if (!unmountRef.current && ref.instance.uri.toString() === uriStr) { | ||
documentModelRef.current = ref; | ||
openDocumentModel() | ||
} else { | ||
ref.dispose(); | ||
} | ||
}); | ||
} | ||
} | ||
createModelReference(originalFetchingUriRef, originalUriStr, originalDocumentModelRef) | ||
createModelReference(modifiedFetchingUriRef, modifiedUriStr, modifiedDocumentModelRef) | ||
}, [originalUriStr, modifiedUriStr]) | ||
|
||
return <div ref={containerRef} {...props}></div>; | ||
}; | ||
|
||
export const DiffEditor = (props: ICodeEditorProps) => { | ||
const appContext = useContext(AppContext) | ||
if (!appContext.app) return null | ||
return ( | ||
<ConfigProvider value={appContext.app.config}> | ||
<DiffEditorComponent {...props} /> | ||
</ConfigProvider> | ||
) | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,7 @@ | ||
import { createContext } from 'react' | ||
import { ClientApp } from '@codeblitzjs/ide-sumi-core' | ||
|
||
export const AppContext = createContext<{ app: ClientApp | null }>({ app: null }) | ||
export const AppContext = createContext<{ | ||
app: ClientApp | null, | ||
startState?: { status: 'loading' | 'success' | 'error', error?: string } | ||
}>({ app: null }) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { URI } from '@opensumi/ide-core-browser'; | ||
import * as path from 'path' | ||
|
||
export const parseUri = (uriInput: URI | string, workspaceDir: string) => { | ||
if (typeof uriInput === 'string') { | ||
let uri = URI.parse(uriInput) | ||
// 说明传的是路径 | ||
if (uri.scheme === 'file' && !uriInput.startsWith('file:')) { | ||
uri = uri.withPath(path.join(workspaceDir, uri.codeUri.path)) | ||
} | ||
return uri.toString(); | ||
} | ||
return uriInput.toString() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { Autowired, Injectable, Provider } from '@opensumi/di'; | ||
import { BrowserModule } from '@opensumi/ide-core-browser'; | ||
import { IEditorDocumentModelContentProvider, BrowserEditorContribution, IEditorDocumentModelContentRegistry } from '@opensumi/ide-editor/lib/browser' | ||
import { URI, Emitter, Event, Domain } from '@opensumi/ide-core-common' | ||
|
||
const contentMap = { | ||
'a1.js': `const add = (x, y) => { | ||
return x + y | ||
} | ||
`, | ||
'a2.js': `const add = (x, y) => { | ||
return x + y + 1 | ||
} | ||
`, | ||
} | ||
|
||
@Injectable() | ||
export class SampleSchemeDocumentProvider implements IEditorDocumentModelContentProvider { | ||
handlesScheme(scheme: string) { | ||
return scheme === 'sample'; | ||
} | ||
|
||
async provideEditorDocumentModelContent(uri: URI): Promise<string> { | ||
return contentMap[uri.codeUri.path.slice(1)] | ||
} | ||
|
||
isReadonly() { | ||
return true; | ||
} | ||
|
||
private _onDidChangeContent: Emitter<URI> = new Emitter(); | ||
onDidChangeContent: Event<URI> = this._onDidChangeContent.event; | ||
} | ||
|
||
@Domain(BrowserEditorContribution) | ||
class SampleContribution implements BrowserEditorContribution { | ||
@Autowired(SampleSchemeDocumentProvider) | ||
private readonly sampleSchemeDocumentProvider: SampleSchemeDocumentProvider; | ||
|
||
registerEditorDocumentModelContentProvider(registry: IEditorDocumentModelContentRegistry): void { | ||
registry.registerEditorDocumentModelContentProvider(this.sampleSchemeDocumentProvider) | ||
} | ||
} | ||
|
||
@Injectable() | ||
export class SampleModule extends BrowserModule { | ||
providers: Provider[] = [SampleContribution]; | ||
} |