feat: introduce apply button functionality (v0.1)
### Summary - Added a new "Apply" button to code snippets provided by the AI assistant. - The button is designed to seamlessly merge the AI-generated snippet into the relevant file in the editor. ### Current Issues 1. **Sticky Accept/Decline Buttons:** These activate for every snippet instead of being limited to the relevant snippet. 2. **Discard Button:** Currently non-functional. 3. **Highlight Inconsistencies:** The green-red code highlights for old and new code are inconsistent. ### To Do - Implement a toast notification when the "Apply" button is pressed on an irrelevant tab to prevent code application errors. ### Workflow Implemented 1. The "Apply" button is added alongside "Copy" and "Reply" for AI-generated code snippets. 2. Upon clicking "Apply," the code snippet and relevant file content (active file) are sent to a secondary model (GPT-4O). 3. The system prompt for GPT-4O instructs it to merge the snippet with the file content: - Ensure the original file functionality remains intact. - Integrate the code snippet seamlessly. 4. The output from GPT-4O is injected directly into the code editor. 5. Changes are visually highlighted: - Green for new code. - Red for removed code. 6. Highlights remain until the user explicitly accepts or discards the changes.
This commit is contained in:
@ -104,6 +104,13 @@ export default function CodeEditor({
|
||||
// Added this state to track the most recent content for each file
|
||||
const [fileContents, setFileContents] = useState<Record<string, string>>({})
|
||||
|
||||
// Apply Button merger decoration state
|
||||
const [mergeDecorations, setMergeDecorations] = useState<
|
||||
monaco.editor.IModelDeltaDecoration[]
|
||||
>([])
|
||||
const [mergeDecorationsCollection, setMergeDecorationsCollection] =
|
||||
useState<monaco.editor.IEditorDecorationsCollection>()
|
||||
|
||||
// Editor state
|
||||
const [editorLanguage, setEditorLanguage] = useState("plaintext")
|
||||
const [cursorLine, setCursorLine] = useState(0)
|
||||
@ -375,6 +382,49 @@ export default function CodeEditor({
|
||||
})
|
||||
}, [editorRef])
|
||||
|
||||
// handle apply code
|
||||
const handleApplyCode = useCallback(
|
||||
(mergedCode: string) => {
|
||||
if (!editorRef) return
|
||||
|
||||
const originalLines = activeFileContent.split("\n")
|
||||
const mergedLines = mergedCode.split("\n")
|
||||
|
||||
const decorations: monaco.editor.IModelDeltaDecoration[] = []
|
||||
|
||||
for (
|
||||
let i = 0;
|
||||
i < Math.max(originalLines.length, mergedLines.length);
|
||||
i++
|
||||
) {
|
||||
if (originalLines[i] !== mergedLines[i]) {
|
||||
decorations.push({
|
||||
range: new monaco.Range(i + 1, 1, i + 1, 1),
|
||||
options: {
|
||||
isWholeLine: true,
|
||||
className:
|
||||
i < originalLines.length
|
||||
? "removed-line-decoration"
|
||||
: "added-line-decoration",
|
||||
glyphMarginClassName:
|
||||
i < originalLines.length
|
||||
? "removed-line-glyph"
|
||||
: "added-line-glyph",
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Update editor content
|
||||
editorRef.setValue(mergedCode)
|
||||
|
||||
// Apply decorations
|
||||
const newDecorations = editorRef.createDecorationsCollection(decorations)
|
||||
setMergeDecorationsCollection(newDecorations)
|
||||
},
|
||||
[editorRef, activeFileContent]
|
||||
)
|
||||
|
||||
// Generate widget effect
|
||||
useEffect(() => {
|
||||
if (generate.show) {
|
||||
@ -1234,6 +1284,9 @@ export default function CodeEditor({
|
||||
lastCopiedRangeRef={lastCopiedRangeRef}
|
||||
files={files}
|
||||
templateType={sandboxData.type}
|
||||
handleApplyCode={handleApplyCode}
|
||||
mergeDecorationsCollection={mergeDecorationsCollection}
|
||||
setMergeDecorationsCollection={setMergeDecorationsCollection}
|
||||
/>
|
||||
</ResizablePanel>
|
||||
</>
|
||||
|
Reference in New Issue
Block a user