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:
@ -1,15 +1,23 @@
|
||||
import { CornerUpLeft } from "lucide-react"
|
||||
import { Check, CornerUpLeft, X } from "lucide-react"
|
||||
import monaco from "monaco-editor"
|
||||
import { Components } from "react-markdown"
|
||||
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"
|
||||
import { vscDarkPlus } from "react-syntax-highlighter/dist/esm/styles/prism"
|
||||
import { Button } from "../../../ui/button"
|
||||
import ApplyButton from "../ApplyButton"
|
||||
import { stringifyContent } from "./chatUtils"
|
||||
|
||||
// Create markdown components for chat message component
|
||||
export const createMarkdownComponents = (
|
||||
renderCopyButton: (text: any) => JSX.Element,
|
||||
renderMarkdownElement: (props: any) => JSX.Element,
|
||||
askAboutCode: (code: any) => void
|
||||
askAboutCode: (code: any) => void,
|
||||
activeFileName: string,
|
||||
activeFileContent: string,
|
||||
editorRef: any,
|
||||
handleApplyCode: (mergedCode: string) => void,
|
||||
mergeDecorationsCollection?: monaco.editor.IEditorDecorationsCollection,
|
||||
setMergeDecorationsCollection?: (collection: undefined) => void
|
||||
): Components => ({
|
||||
code: ({
|
||||
node,
|
||||
@ -33,6 +41,57 @@ export const createMarkdownComponents = (
|
||||
<div className="flex border border-input shadow-lg bg-background rounded-md">
|
||||
{renderCopyButton(children)}
|
||||
<div className="w-px bg-input"></div>
|
||||
{!mergeDecorationsCollection ? (
|
||||
<ApplyButton
|
||||
code={String(children)}
|
||||
activeFileName={activeFileName}
|
||||
activeFileContent={activeFileContent}
|
||||
editorRef={editorRef}
|
||||
onApply={handleApplyCode}
|
||||
/>
|
||||
) : (
|
||||
<>
|
||||
<Button
|
||||
onClick={() => {
|
||||
if (
|
||||
setMergeDecorationsCollection &&
|
||||
mergeDecorationsCollection &&
|
||||
editorRef?.current
|
||||
) {
|
||||
mergeDecorationsCollection.clear()
|
||||
setMergeDecorationsCollection(undefined)
|
||||
}
|
||||
}}
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
className="p-1 h-6"
|
||||
title="Accept Changes"
|
||||
>
|
||||
<Check className="w-4 h-4 text-green-500" />
|
||||
</Button>
|
||||
<div className="w-px bg-input"></div>
|
||||
<Button
|
||||
onClick={() => {
|
||||
if (
|
||||
setMergeDecorationsCollection &&
|
||||
mergeDecorationsCollection &&
|
||||
editorRef?.current
|
||||
) {
|
||||
editorRef.current.getModel()?.setValue(activeFileContent)
|
||||
mergeDecorationsCollection.clear()
|
||||
setMergeDecorationsCollection(undefined)
|
||||
}
|
||||
}}
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
className="p-1 h-6"
|
||||
title="Discard Changes"
|
||||
>
|
||||
<X className="w-4 h-4 text-red-500" />
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
<div className="w-px bg-input"></div>
|
||||
<Button
|
||||
onClick={(e) => {
|
||||
e.preventDefault()
|
||||
|
Reference in New Issue
Block a user