-
Notifications
You must be signed in to change notification settings - Fork 400
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: support diff & git uri preview of notebook file (#4323)
* feat: 支持 notebook git uri 预览 * feat: 完成diff新增cell能力开发 * feat: 支持cell diff * feat: support delete & unchanged cell diff * fix: fix notebook git uri * fix: dispose editors * fix: update dependency on editorTargetRef current value * fix: lint problem * fix: missing deps * chore: update lock
- Loading branch information
Showing
20 changed files
with
1,580 additions
and
7 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { Container, URI, ViewRender } from '@difizen/mana-app'; | ||
import React, { useEffect, useState } from 'react'; | ||
|
||
import { useInjectable } from '@opensumi/ide-core-browser'; | ||
import { ReactEditorComponent } from '@opensumi/ide-editor/lib/browser/types'; | ||
|
||
import { LibroVersionManager } from './libro/diff-view/libro-version-manager'; | ||
import { AIStudioLibroVersionView } from './libro/diff-view/libro-version-view'; | ||
import { ContentLoaderType, ManaContainer } from './mana'; | ||
|
||
export const LibroVersionPreview: ReactEditorComponent = ({ resource }) => { | ||
const uri = resource.uri; | ||
const originalUri = uri.scheme === 'diff' ? new URI(decodeURIComponent(uri.getParsedQuery().original)) : undefined; | ||
const targetUri = uri.scheme === 'diff' ? new URI(decodeURIComponent(uri.getParsedQuery().modified)) : undefined; | ||
const manaContainer = useInjectable<Container>(ManaContainer); | ||
const libroVersionManager = manaContainer.get(LibroVersionManager); | ||
const [versionView, setVersionView] = useState<AIStudioLibroVersionView>(); | ||
|
||
useEffect(() => { | ||
libroVersionManager | ||
.getOrCreateView({ | ||
resource: uri.toString(), | ||
loadType: ContentLoaderType, | ||
originalUri, | ||
targetUri, | ||
}) | ||
.then((view) => { | ||
setVersionView(view); | ||
}); | ||
}, [uri]); | ||
|
||
return <div className='libro-version'>{versionView && <ViewRender view={versionView}></ViewRender>}</div>; | ||
}; |
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 |
---|---|---|
@@ -1,2 +1,4 @@ | ||
export const LIBRO_COMPONENTS_ID = 'opensumi:libro'; | ||
export const LIBRO_COMPONENT_ID = 'opensumi:libro'; | ||
export const LIBRO_PREVIEW_COMPONENT_ID = 'opensumi:libro-preview'; | ||
export const LIBRO_DIFF_COMPONENT_ID = 'opensumi:libro-diff'; | ||
export const LIBRO_COMPONENTS_SCHEME_ID = 'ipynb'; |
123 changes: 123 additions & 0 deletions
123
packages/notebook/src/browser/libro/diff-view/components/hooks.tsx
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,123 @@ | ||
import { useCallback, useEffect, useLayoutEffect, useRef } from 'react'; | ||
import ResizeObserver from 'resize-observer-polyfill'; | ||
|
||
import { ICodeEditor, IDiffEditor } from '@opensumi/ide-monaco'; | ||
|
||
export interface Size { | ||
width?: number; | ||
height?: number; | ||
} | ||
|
||
function useLatest<T>(value: T) { | ||
const ref = useRef(value); | ||
ref.current = value; | ||
|
||
return ref; | ||
} | ||
|
||
export default useLatest; | ||
export function useSize(fn: () => void, ref: React.ForwardedRef<HTMLDivElement>): void { | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
const callback = useLatest((size: Size) => { | ||
fn(); | ||
}); | ||
useLayoutEffect(() => { | ||
if (typeof ref !== 'object') { | ||
return () => {}; | ||
} | ||
const el = ref?.current; | ||
if (!el || !fn) { | ||
return () => {}; | ||
} | ||
const resizeObserver = new ResizeObserver((entries) => { | ||
entries.forEach((entry) => { | ||
callback.current({ | ||
width: entry.target.clientWidth, | ||
height: entry.target.clientHeight, | ||
}); | ||
}); | ||
}); | ||
|
||
resizeObserver.observe(el as HTMLElement); | ||
return () => { | ||
resizeObserver.disconnect(); | ||
}; | ||
}, [callback, ref, fn]); | ||
} | ||
|
||
const setEditorHeight = ( | ||
editor: ICodeEditor | undefined, | ||
editorTarget: HTMLDivElement, | ||
editorContainer: HTMLDivElement, | ||
) => { | ||
if (!editor) { | ||
return; | ||
} | ||
const curLenght = editor.getModel()?.getLineCount() || 1; | ||
const diffItemHeight = `${curLenght * 20 + 16 + 12 + 22}px`; | ||
const _height = `${curLenght * 20}px`; | ||
if (editorTarget.style.height !== _height) { | ||
editorTarget.style.height = _height; | ||
editorContainer.style.height = diffItemHeight; | ||
editor.layout(); | ||
} | ||
}; | ||
|
||
const setDiffEditorHeight = ( | ||
editor: IDiffEditor | undefined, | ||
editorTarget: HTMLDivElement, | ||
editorContainer: HTMLDivElement, | ||
) => { | ||
const originalLineCount = editor?.getModel()?.original.getLineCount() || 0; | ||
|
||
editor?.onDidUpdateDiff(() => { | ||
let finalLineCount = originalLineCount; | ||
for (const change of editor?.getLineChanges() || []) { | ||
if (!change.originalEndLineNumber) { | ||
finalLineCount += change.modifiedEndLineNumber - change.modifiedStartLineNumber + 1; | ||
} else if ( | ||
change.originalStartLineNumber === change.modifiedStartLineNumber && | ||
change.modifiedEndLineNumber > change.originalEndLineNumber | ||
) { | ||
finalLineCount += change.modifiedEndLineNumber - change.originalEndLineNumber; | ||
} | ||
} | ||
editorTarget.style.height = `${finalLineCount * 20 + 12}px`; | ||
editorContainer.style.height = `${finalLineCount * 20 + 16 + 12 + 22}px`; | ||
editor.layout(); | ||
}); | ||
}; | ||
|
||
export function useEditorLayout( | ||
editor: ICodeEditor | IDiffEditor | undefined, | ||
editorTargetRef: React.RefObject<HTMLDivElement>, | ||
editorContainerRef: React.RefObject<HTMLDivElement>, | ||
) { | ||
const editorTarget = editorTargetRef.current; | ||
const editorContainer = editorContainerRef.current; | ||
|
||
const editorLaylout = useCallback(() => { | ||
if (editor) { | ||
editor.layout(); | ||
} | ||
}, [editor]); | ||
|
||
useEffect(() => { | ||
if (editor) { | ||
if (!editorTarget || !editorContainer) { | ||
return; | ||
} | ||
if ((editor as IDiffEditor).renderSideBySide !== undefined) { | ||
setDiffEditorHeight(editor as IDiffEditor, editorTarget, editorContainer); | ||
} else { | ||
setEditorHeight(editor as ICodeEditor, editorTarget, editorContainer); | ||
} | ||
} | ||
window.addEventListener('resize', editorLaylout); | ||
return () => { | ||
window.removeEventListener('resize', editorLaylout); | ||
}; | ||
}, [editor, editorLaylout]); | ||
|
||
useSize(editorLaylout, editorContainerRef); | ||
} |
Oops, something went wrong.
54bc272
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉 Next publish successful!
3.7.1-next-1737368070.0