Skip to content

Commit 61a3bf8

Browse files
committed
Fix panel flicker and preserve editor view during file switches
1 parent c27bf24 commit 61a3bf8

2 files changed

Lines changed: 32 additions & 15 deletions

File tree

anycode/components/layout/Layout.tsx

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -880,21 +880,26 @@ export const Layout: React.FC<LayoutProps> = ({
880880
};
881881
}, []);
882882

883+
const applyPanelViewStates = useCallback(() => {
884+
Object.entries(panelViewStatesRef.current).forEach(([panelKey, state]) => {
885+
panelViewStateHandlersRef.current.get(panelKey)?.restoreViewState(state);
886+
});
887+
}, []);
888+
883889
const restorePanelViewStates = useCallback(() => {
884890
if (restoreViewStatesFrameRef.current !== null) {
885891
cancelAnimationFrame(restoreViewStatesFrameRef.current);
886892
}
887893

888-
restoreViewStatesFrameRef.current = requestAnimationFrame(() => {
889-
restoreViewStatesFrameRef.current = requestAnimationFrame(() => {
890-
restoreViewStatesFrameRef.current = null;
894+
// Apply immediately to avoid a visible one-frame jump to scrollTop=0.
895+
applyPanelViewStates();
891896

892-
Object.entries(panelViewStatesRef.current).forEach(([panelKey, state]) => {
893-
panelViewStateHandlersRef.current.get(panelKey)?.restoreViewState(state);
894-
});
895-
});
897+
// Run one follow-up pass in the next frame for content that mounts asynchronously.
898+
restoreViewStatesFrameRef.current = requestAnimationFrame(() => {
899+
restoreViewStatesFrameRef.current = null;
900+
applyPanelViewStates();
896901
});
897-
}, []);
902+
}, [applyPanelViewStates]);
898903

899904
const queueSaveLayout = useCallback((api: DockviewApi) => {
900905
if (layoutSaveTimerRef.current !== null) {
@@ -1144,7 +1149,7 @@ export const Layout: React.FC<LayoutProps> = ({
11441149
apiRef.current = null;
11451150
}, [disposeListeners]);
11461151

1147-
useEffect(() => {
1152+
useLayoutEffect(() => {
11481153
const api = apiRef.current;
11491154
if (!api) {
11501155
return;

anycode/features/editor/EditorPanel.tsx

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
import { AnycodeEditorReact } from 'anycode-react';
1+
import { useEffect, useState } from 'react';
2+
import { AnycodeEditor, AnycodeEditorReact } from 'anycode-react';
23
import type { ReferencesPeekState } from '../../types';
34
import { ReferencesPeek } from './ReferencesPeek';
45

56
type EditorPanelProps = {
67
panelKey: string;
78
editors: {
89
files: Array<{ id: string }>;
9-
editorStates: ReadonlyMap<string, unknown>;
10+
editorStates: ReadonlyMap<string, AnycodeEditor>;
1011
getActiveFileIdForPane: (paneId: string) => string | null;
1112
setActiveEditorPaneId: (paneId: string) => void;
1213
getReferencesPeekForPane: (paneId: string) => ReferencesPeekState | null;
@@ -22,17 +23,28 @@ export const EditorPanel = ({ panelKey, editors }: EditorPanelProps) => {
2223
const paneFile = paneFileId ? editors.files.find((file) => file.id === paneFileId) : null;
2324
const editorState = paneFile ? editors.editorStates.get(paneFile.id) : null;
2425
const referencesPeek = editors.getReferencesPeekForPane(panelKey);
26+
const [lastReadyEditor, setLastReadyEditor] = useState<{ id: string; state: AnycodeEditor } | null>(null);
27+
28+
useEffect(() => {
29+
if (paneFile && editorState) {
30+
setLastReadyEditor({ id: paneFile.id, state: editorState });
31+
}
32+
}, [paneFile, editorState]);
33+
34+
const displayedEditor = paneFile && editorState
35+
? { id: paneFile.id, state: editorState }
36+
: lastReadyEditor;
2537

2638
return (
2739
<div
2840
className="editor-container"
2941
onMouseDown={() => editors.setActiveEditorPaneId(panelKey)}
3042
>
31-
{paneFile && editorState ? (
43+
{displayedEditor ? (
3244
<AnycodeEditorReact
33-
key={`${panelKey}:${paneFile.id}`}
34-
id={paneFile.id}
35-
editorState={editorState as never}
45+
key={`${panelKey}:${displayedEditor.id}`}
46+
id={displayedEditor.id}
47+
editorState={displayedEditor.state}
3648
/>
3749
) : (
3850
<div className="no-editor"></div>

0 commit comments

Comments
 (0)