diff --git a/apps/code/src/renderer/features/code-review/components/CommentAnnotation.tsx b/apps/code/src/renderer/features/code-review/components/CommentAnnotation.tsx index e8ad71f9a..244531125 100644 --- a/apps/code/src/renderer/features/code-review/components/CommentAnnotation.tsx +++ b/apps/code/src/renderer/features/code-review/components/CommentAnnotation.tsx @@ -1,9 +1,10 @@ import { sendPromptToAgent } from "@features/sessions/utils/sendPromptToAgent"; import { PaperPlaneTilt, X } from "@phosphor-icons/react"; import type { AnnotationSide } from "@pierre/diffs"; -import { Button, IconButton } from "@radix-ui/themes"; +import { Button, Checkbox, Flex, IconButton, Text } from "@radix-ui/themes"; import { isSendMessageSubmitKey } from "@utils/sendMessageKey"; -import { useCallback, useRef } from "react"; +import { useCallback, useEffect, useRef, useState } from "react"; +import { useReviewDraftsStore } from "../stores/reviewDraftsStore"; import { buildInlineCommentPrompt } from "../utils/reviewPrompts"; interface CommentAnnotationProps { @@ -13,6 +14,8 @@ interface CommentAnnotationProps { endLine: number; side: AnnotationSide; onDismiss: () => void; + initialText?: string; + editingDraftId?: string; } export function CommentAnnotation({ @@ -22,28 +25,78 @@ export function CommentAnnotation({ endLine, side, onDismiss, + initialText, + editingDraftId, }: CommentAnnotationProps) { const textareaRef = useRef(null); + const addDraft = useReviewDraftsStore((s) => s.addDraft); + const updateDraft = useReviewDraftsStore((s) => s.updateDraft); + const setBatchEnabled = useReviewDraftsStore((s) => s.setBatchEnabled); + const initialBatchEnabled = useReviewDraftsStore((s) => + s.isBatchEnabled(taskId), + ); - const setTextareaRef = useCallback((el: HTMLTextAreaElement | null) => { - ( - textareaRef as React.MutableRefObject - ).current = el; - if (el) { - requestAnimationFrame(() => el.focus()); - } - }, []); + const [batch, setBatch] = useState( + editingDraftId ? true : initialBatchEnabled, + ); + + const setTextareaRef = useCallback( + (el: HTMLTextAreaElement | null) => { + ( + textareaRef as React.MutableRefObject + ).current = el; + if (el) { + if (initialText !== undefined) { + el.value = initialText; + } + requestAnimationFrame(() => el.focus()); + } + }, + [initialText], + ); + + // Keep the checkbox in sync if another action toggles batchEnabled while + // this textarea is open (e.g. user adds a draft elsewhere). + useEffect(() => { + if (editingDraftId) return; + setBatch(initialBatchEnabled); + }, [initialBatchEnabled, editingDraftId]); const handleSubmit = useCallback(() => { const text = textareaRef.current?.value?.trim(); - if (text) { + if (!text) return; + + if (editingDraftId) { + updateDraft(taskId, editingDraftId, text); onDismiss(); - sendPromptToAgent( - taskId, - buildInlineCommentPrompt(filePath, startLine, endLine, side, text), - ); + return; } - }, [taskId, filePath, startLine, endLine, side, onDismiss]); + + if (batch) { + addDraft(taskId, { filePath, startLine, endLine, side, text }); + setBatchEnabled(taskId, true); + onDismiss(); + return; + } + + onDismiss(); + sendPromptToAgent( + taskId, + buildInlineCommentPrompt(filePath, startLine, endLine, side, text), + ); + }, [ + taskId, + filePath, + startLine, + endLine, + side, + onDismiss, + batch, + editingDraftId, + addDraft, + updateDraft, + setBatchEnabled, + ]); const handleKeyDown = useCallback( (e: React.KeyboardEvent) => { @@ -59,27 +112,52 @@ export function CommentAnnotation({ [handleSubmit, onDismiss], ); + const submitLabel = editingDraftId + ? "Update comment" + : batch + ? "Add to review" + : "Send to agent"; + return (