mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-06-12 09:24:29 +02:00
Intelligent readonly editor updates, to preserve scroll
This commit is contained in:
@@ -8,12 +8,12 @@ import classNames from 'classnames';
|
|||||||
import { EditorView } from 'codemirror';
|
import { EditorView } from 'codemirror';
|
||||||
import type { MutableRefObject, ReactNode } from 'react';
|
import type { MutableRefObject, ReactNode } from 'react';
|
||||||
import {
|
import {
|
||||||
|
useEffect,
|
||||||
Children,
|
Children,
|
||||||
cloneElement,
|
cloneElement,
|
||||||
forwardRef,
|
forwardRef,
|
||||||
isValidElement,
|
isValidElement,
|
||||||
useCallback,
|
useCallback,
|
||||||
useEffect,
|
|
||||||
useImperativeHandle,
|
useImperativeHandle,
|
||||||
useMemo,
|
useMemo,
|
||||||
useRef,
|
useRef,
|
||||||
@@ -343,6 +343,33 @@ export const Editor = forwardRef<EditorView | undefined, EditorProps>(function E
|
|||||||
[forceUpdateKey],
|
[forceUpdateKey],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// For read-only mode, update content when `defaultValue` changes
|
||||||
|
useEffect(() => {
|
||||||
|
if (!readOnly || cm.current?.view == null || defaultValue == null) return;
|
||||||
|
|
||||||
|
// Replace codemirror contents
|
||||||
|
const currentDoc = cm.current.view.state.doc.toString();
|
||||||
|
if (defaultValue.startsWith(currentDoc)) {
|
||||||
|
// If we're just appending, append only the changes. This preserves
|
||||||
|
// things like scroll position.
|
||||||
|
cm.current.view.dispatch({
|
||||||
|
changes: cm.current.view.state.changes({
|
||||||
|
from: currentDoc.length,
|
||||||
|
insert: defaultValue.slice(currentDoc.length),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// If we're replacing everything, reset the entire content
|
||||||
|
cm.current.view.dispatch({
|
||||||
|
changes: cm.current.view.state.changes({
|
||||||
|
from: 0,
|
||||||
|
to: currentDoc.length,
|
||||||
|
insert: currentDoc,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [defaultValue, readOnly]);
|
||||||
|
|
||||||
// Add bg classes to actions, so they appear over the text
|
// Add bg classes to actions, so they appear over the text
|
||||||
const decoratedActions = useMemo(() => {
|
const decoratedActions = useMemo(() => {
|
||||||
const results = [];
|
const results = [];
|
||||||
|
|||||||
@@ -90,7 +90,6 @@ function ActualEventStreamViewer({ response }: Props) {
|
|||||||
) : (
|
) : (
|
||||||
<Editor
|
<Editor
|
||||||
readOnly
|
readOnly
|
||||||
forceUpdateKey={activeEvent.id ?? activeEvent.data}
|
|
||||||
defaultValue={tryFormatJson(activeEvent.data)}
|
defaultValue={tryFormatJson(activeEvent.data)}
|
||||||
language={language}
|
language={language}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -160,7 +160,6 @@ export function TextViewer({
|
|||||||
<Editor
|
<Editor
|
||||||
readOnly
|
readOnly
|
||||||
className={className}
|
className={className}
|
||||||
forceUpdateKey={body}
|
|
||||||
defaultValue={body}
|
defaultValue={body}
|
||||||
language={language}
|
language={language}
|
||||||
actions={actions}
|
actions={actions}
|
||||||
|
|||||||
Reference in New Issue
Block a user