mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-25 08:06:48 +08:00
### What problem does this PR solve? feat(agent): Added history management and paste handling features #3221 - Added a PasteHandlerPlugin to handle paste operations, optimizing the multi-line text pasting experience - Implemented the AgentHistoryManager class to manage history, supporting undo and redo functionality - Integrates history management functionality into the Agent component ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
@ -26,6 +26,7 @@ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext
|
||||
import { Variable } from 'lucide-react';
|
||||
import { ReactNode, useCallback, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PasteHandlerPlugin } from './paste-handler-plugin';
|
||||
import theme from './theme';
|
||||
import { VariableNode } from './variable-node';
|
||||
import { VariableOnChangePlugin } from './variable-on-change-plugin';
|
||||
@ -172,6 +173,7 @@ export function PromptEditor({
|
||||
ErrorBoundary={LexicalErrorBoundary}
|
||||
/>
|
||||
<VariablePickerMenuPlugin value={value}></VariablePickerMenuPlugin>
|
||||
<PasteHandlerPlugin />
|
||||
<VariableOnChangePlugin
|
||||
onChange={onValueChange}
|
||||
></VariableOnChangePlugin>
|
||||
|
||||
@ -0,0 +1,83 @@
|
||||
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
||||
import {
|
||||
$createParagraphNode,
|
||||
$createTextNode,
|
||||
$getSelection,
|
||||
$isRangeSelection,
|
||||
PASTE_COMMAND,
|
||||
} from 'lexical';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
function PasteHandlerPlugin() {
|
||||
const [editor] = useLexicalComposerContext();
|
||||
useEffect(() => {
|
||||
const removeListener = editor.registerCommand(
|
||||
PASTE_COMMAND,
|
||||
(clipboardEvent: ClipboardEvent) => {
|
||||
const clipboardData = clipboardEvent.clipboardData;
|
||||
if (!clipboardData) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const text = clipboardData.getData('text/plain');
|
||||
if (!text) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if text contains line breaks
|
||||
if (text.includes('\n')) {
|
||||
editor.update(() => {
|
||||
const selection = $getSelection();
|
||||
if (selection && $isRangeSelection(selection)) {
|
||||
// Normalize line breaks, merge multiple consecutive line breaks into a single line break
|
||||
const normalizedText = text.replace(/\n{2,}/g, '\n');
|
||||
|
||||
// Clear current selection
|
||||
selection.removeText();
|
||||
|
||||
// Create a paragraph node to contain all content
|
||||
const paragraph = $createParagraphNode();
|
||||
|
||||
// Split text by line breaks
|
||||
const lines = normalizedText.split('\n');
|
||||
|
||||
// Process each line
|
||||
lines.forEach((lineText, index) => {
|
||||
// Add line text (if any)
|
||||
if (lineText) {
|
||||
const textNode = $createTextNode(lineText);
|
||||
paragraph.append(textNode);
|
||||
}
|
||||
|
||||
// If not the last line, add a line break
|
||||
if (index < lines.length - 1) {
|
||||
const lineBreak = $createTextNode('\n');
|
||||
paragraph.append(lineBreak);
|
||||
}
|
||||
});
|
||||
|
||||
// Insert paragraph
|
||||
selection.insertNodes([paragraph]);
|
||||
}
|
||||
});
|
||||
|
||||
// Prevent default paste behavior
|
||||
clipboardEvent.preventDefault();
|
||||
return true;
|
||||
}
|
||||
|
||||
// If no line breaks, use default behavior
|
||||
return false;
|
||||
},
|
||||
4,
|
||||
);
|
||||
|
||||
return () => {
|
||||
removeListener();
|
||||
};
|
||||
}, [editor]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export { PasteHandlerPlugin };
|
||||
Reference in New Issue
Block a user