Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import {
extractCloudFileDiff,
type ParsedToolCall,
} from "@features/task-detail/utils/cloudToolChanges";
import type { FileDiffOptions } from "@pierre/diffs";
import { MultiFileDiff } from "@pierre/diffs/react";
import { Flex, Spinner, Text } from "@radix-ui/themes";
import type { ChangedFile, Task } from "@shared/types";
import type { AcpMessage } from "@shared/types/session-events";
import { useMemo } from "react";
import { useReviewComment } from "../hooks/useReviewComment";
import type { DiffOptions, OnCommentCallback } from "../types";
import { InteractiveFileDiff } from "./InteractiveFileDiff";
import {
DeferredDiffPlaceholder,
DiffFileHeader,
Expand All @@ -33,6 +34,7 @@ export function CloudReviewPage({ taskId, task }: CloudReviewPageProps) {
changedFiles,
isLoading,
} = useCloudChangedFiles(taskId, task);
const onComment = useReviewComment(taskId);
const events = session?.events ?? EMPTY_EVENTS;
const summary = useMemo(() => buildCloudEventSummary(events), [events]);

Expand Down Expand Up @@ -117,6 +119,7 @@ export function CloudReviewPage({ taskId, task }: CloudReviewPageProps) {
options={diffOptions}
collapsed={isCollapsed}
onToggle={() => toggleFile(file.path)}
onComment={onComment}
/>
</div>
);
Expand All @@ -131,12 +134,14 @@ function CloudFileDiff({
options,
collapsed,
onToggle,
onComment,
}: {
file: ChangedFile;
toolCalls: Map<string, ParsedToolCall>;
options: FileDiffOptions<unknown>;
options: DiffOptions;
collapsed: boolean;
onToggle: () => void;
onComment: OnCommentCallback;
}) {
const diff = useMemo(
() => extractCloudFileDiff(toolCalls, file.path),
Expand All @@ -154,10 +159,11 @@ function CloudFileDiff({
);

return (
<MultiFileDiff
<InteractiveFileDiff
oldFile={oldFile}
newFile={newFile}
options={{ ...options, collapsed }}
onComment={onComment}
renderCustomHeader={(fd) => (
<DiffFileHeader
fileDiff={fd}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { useCallback, useRef } from "react";

interface CommentAnnotationProps {
onSubmit: (text: string) => void;
onCancel: () => void;
}

export function CommentAnnotation({
onSubmit,
onCancel,
}: CommentAnnotationProps) {
const textareaRef = useRef<HTMLTextAreaElement>(null);

const setTextareaRef = useCallback((el: HTMLTextAreaElement | null) => {
(
textareaRef as React.MutableRefObject<HTMLTextAreaElement | null>
).current = el;
if (el) {
requestAnimationFrame(() => el.focus());
}
}, []);

const handleSubmit = useCallback(() => {
const text = textareaRef.current?.value?.trim();
if (text) {
onSubmit(text);
}
}, [onSubmit]);

const handleKeyDown = useCallback(
(e: React.KeyboardEvent) => {
if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
e.preventDefault();
handleSubmit();
}
if (e.key === "Escape") {
e.preventDefault();
onCancel();
}
},
[handleSubmit, onCancel],
);

return (
<div
data-comment-annotation=""
className="whitespace-normal rounded-md border border-[var(--gray-5)] bg-[var(--gray-2)] px-2 py-2.5"
>
<textarea
ref={setTextareaRef}
placeholder="Describe the changes you'd like..."
onKeyDown={handleKeyDown}
className="w-full resize-none rounded border border-[var(--gray-6)] bg-[var(--color-background)] p-1.5 font-inherit text-[13px] text-[var(--gray-12)] leading-normal outline-none"
style={{ minHeight: 48 }}
/>
<div className="mt-1.5 flex items-center gap-1.5">
<button
type="button"
onClick={handleSubmit}
className="cursor-pointer rounded border-none bg-[var(--accent-9)] px-2.5 py-0.5 font-medium text-[var(--gray-1)] text-xs leading-[18px]"
>
Send to agent
</button>
<button
type="button"
onClick={onCancel}
className="cursor-pointer border-none bg-transparent px-2 py-0.5 text-[var(--gray-9)] text-xs leading-[18px]"
>
Cancel
</button>
</div>
</div>
);
}
Loading
Loading