From d03337c7fa4a9211b38f34a4e971921c634fea20 Mon Sep 17 00:00:00 2001 From: liangfung <1098486429@qq.com> Date: Thu, 23 May 2024 21:26:13 +0800 Subject: [PATCH] refactor(ui): auto scroll active code line into view --- .../app/files/components/code-editor-view.tsx | 8 ++++++-- .../app/files/components/file-tree.tsx | 18 ++++++++++++++++- .../files/components/source-code-browser.tsx | 20 ------------------- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/ee/tabby-ui/app/files/components/code-editor-view.tsx b/ee/tabby-ui/app/files/components/code-editor-view.tsx index a9521d8092f0..407618cf5a41 100644 --- a/ee/tabby-ui/app/files/components/code-editor-view.tsx +++ b/ee/tabby-ui/app/files/components/code-editor-view.tsx @@ -39,7 +39,6 @@ const CodeEditorView: React.FC = ({ value, language }) => { const tags: TCodeTag[] = React.useMemo(() => { return [] }, []) - const initialized = React.useRef(false) const { copyToClipboard } = useCopyToClipboard({}) const line = searchParams.get('line')?.toString() const [editorView, setEditorView] = React.useState(null) @@ -132,11 +131,16 @@ const CodeEditorView: React.FC = ({ value, language }) => { React.useEffect(() => { if (line && editorView && value) { try { - initialized.current = true const lineNumber = parseInt(line) const lineObject = editorView?.state?.doc?.line(lineNumber) if (lineObject) { setSelectedLines(editorView, lineObject.from) + editorView.dispatch({ + effects: EditorView.scrollIntoView(lineObject.from, { + y: 'start', + yMargin: 120 + }) + }) } } catch (e) {} } diff --git a/ee/tabby-ui/app/files/components/file-tree.tsx b/ee/tabby-ui/app/files/components/file-tree.tsx index a7be11f1a845..6fb5962d708c 100644 --- a/ee/tabby-ui/app/files/components/file-tree.tsx +++ b/ee/tabby-ui/app/files/components/file-tree.tsx @@ -26,6 +26,7 @@ import { resolveFileNameFromPath, resolveRepositoryInfoFromPath } from './utils' +import { useInView } from 'react-intersection-observer' type TFileTreeNode = { name: string @@ -136,7 +137,22 @@ const GridArea: React.FC<{ level: number }> = ({ level }) => { } const ActiveViewBar = () => { - return
+ const { ref, entry, inView } = useInView({ + trackVisibility: true, + delay: 500 + }) + + React.useEffect(() => { + if (!!entry?.target && !inView) { + entry?.target?.scrollIntoView({ + block: 'center' + }) + } + }, [entry?.target]) + + return ( +
+ ) } /** diff --git a/ee/tabby-ui/app/files/components/source-code-browser.tsx b/ee/tabby-ui/app/files/components/source-code-browser.tsx index f9f035278924..e512e3054c51 100644 --- a/ee/tabby-ui/app/files/components/source-code-browser.tsx +++ b/ee/tabby-ui/app/files/components/source-code-browser.tsx @@ -434,26 +434,6 @@ const SourceCodeBrowserRenderer: React.FC = ({ } }, [chatSideBarVisible]) - React.useEffect(() => { - const onMessage = (event: MessageEvent) => { - if (event.origin !== window.origin || !event.data) return - - const { data } = event - if (data.action === 'navigateToContext') { - updateSearchParams({ - set: { - path: data.path, - line: data.line - } - }) - } - } - - window.addEventListener('message', onMessage) - - return () => window.removeEventListener('message', onMessage) - }, []) - return (