diff --git a/src/renderer/src/components/right-sidebar/checks-panel-content.tsx b/src/renderer/src/components/right-sidebar/checks-panel-content.tsx index 1ff9669a8..0ffc41dd6 100644 --- a/src/renderer/src/components/right-sidebar/checks-panel-content.tsx +++ b/src/renderer/src/components/right-sidebar/checks-panel-content.tsx @@ -65,12 +65,7 @@ import { type PRCommentAudienceFilter } from '@/lib/pr-comment-audience' import { setPRBotAuthorOverride, usePRBotAuthorOverrides } from '@/lib/pr-bot-author-overrides' -import { - getPRCommentGroupId, - getPRCommentGroupRoot, - groupPRComments, - type PRCommentGroup -} from '@/lib/pr-comment-groups' +import { getPRCommentGroupId, groupPRComments, type PRCommentGroup } from '@/lib/pr-comment-groups' import { getPRCommentGroupActionState, isPRCommentGroupQueueableForAI, @@ -1959,7 +1954,7 @@ function CommentRow({ function PRCommentGroupView({ group, botAuthorOverrides, - replyingGroupId, + replyingCommentId, selectionControl, actionState, isQueued, @@ -1976,7 +1971,7 @@ function PRCommentGroupView({ }: { group: PRCommentGroup botAuthorOverrides: ReadonlySet - replyingGroupId: string | null + replyingCommentId: number | null selectionControl?: React.ReactNode actionState: PRCommentGroupActionState isQueued: boolean @@ -1984,34 +1979,34 @@ function PRCommentGroupView({ replyDisabledReason?: string presentation: PRCommentPresentationClasses onResolve?: (threadId: string, resolve: boolean) => boolean | Promise - onStartReply?: (groupId: string) => void + onStartReply?: (commentId: number) => void onCancelReply?: () => void onReply?: (comment: PRComment, body: string) => Promise onEditComment?: (comment: PRComment, body: string) => Promise onDeleteComment?: (comment: PRComment) => void | Promise onQueueForAgent?: () => void }): React.JSX.Element { - const groupId = getPRCommentGroupId(group) - const root = getPRCommentGroupRoot(group) - const replyComposer = - replyingGroupId === groupId && onReply ? ( + // Reply targets a specific comment id so any comment in a thread — root or + // nested reply — can be replied to, not just the thread root. + const renderReplyComposer = (comment: PRComment): React.ReactNode => + replyingCommentId === comment.id && onReply ? (
onReply(root, body)} + onSubmit={(body) => onReply(comment, body)} />
) : null - const startReply = onStartReply ? () => onStartReply(groupId) : undefined + const startReply = onStartReply ? (comment: PRComment) => onStartReply(comment.id) : undefined const surfaceClassName = cn( getPRCommentGroupSurfaceClasses(presentation, actionState, { queued: isQueued }), group.kind === 'standalone' ? presentation.groupStandalone : presentation.groupThread @@ -2038,10 +2033,10 @@ function PRCommentGroupView({ showResolve={false} showReply={Boolean(onReply)} selectionControl={selectionControl} - onReply={startReply ? () => startReply() : undefined} + onReply={startReply} {...sharedRowProps} /> - {replyComposer} + {renderReplyComposer(group.comment)} ) : (
@@ -2051,25 +2046,28 @@ function PRCommentGroupView({ showResolve={true} showReply={Boolean(onReply)} selectionControl={selectionControl} - onReply={startReply ? () => startReply() : undefined} + onReply={startReply} {...sharedRowProps} /> + {renderReplyComposer(group.root)} {group.replies.length > 0 && (
{group.replies.map((reply) => ( - + + + {renderReplyComposer(reply)} + ))}
)} - {replyComposer}
) @@ -2096,7 +2094,7 @@ function PRCommentGroupView({ function ResolvedCommentGroupsSection({ groups, botAuthorOverrides, - replyingGroupId, + replyingCommentId, replyDisabled, replyDisabledReason, presentation, @@ -2109,12 +2107,12 @@ function ResolvedCommentGroupsSection({ }: { groups: PRCommentGroup[] botAuthorOverrides: ReadonlySet - replyingGroupId: string | null + replyingCommentId: number | null replyDisabled?: boolean replyDisabledReason?: string presentation: PRCommentPresentationClasses onResolve?: (threadId: string, resolve: boolean) => boolean | Promise - onStartReply?: (groupId: string) => void + onStartReply?: (commentId: number) => void onCancelReply?: () => void onReply?: (comment: PRComment, body: string) => Promise onEditComment?: (comment: PRComment, body: string) => Promise @@ -2142,7 +2140,7 @@ function ResolvedCommentGroupsSection({ key={getPRCommentGroupId(group)} group={group} botAuthorOverrides={botAuthorOverrides} - replyingGroupId={replyingGroupId} + replyingCommentId={replyingCommentId} actionState="resolved" isQueued={false} replyDisabled={replyDisabled} @@ -2241,7 +2239,7 @@ export function PRCommentsList({ const presentation = React.useMemo(() => getPRCommentPresentationClasses(), []) const [commentFilter, setCommentFilter] = useState('all') const [displayMode, setDisplayMode] = useState('triage') - const [replyingGroupId, setReplyingGroupId] = useState(null) + const [replyingCommentId, setReplyingCommentId] = useState(null) const [isAddingComment, setIsAddingComment] = useState(false) const addCommentSurfaceRef = useRef(null) const shouldScrollAddCommentRef = useRef(false) @@ -2344,7 +2342,7 @@ export function PRCommentsList({ key={groupId} group={group} botAuthorOverrides={botAuthorOverrides} - replyingGroupId={replyingGroupId} + replyingCommentId={replyingCommentId} selectionControl={renderSelectionControl(group)} actionState={actionState} isQueued={isQueued} @@ -2352,8 +2350,8 @@ export function PRCommentsList({ replyDisabledReason={commentsDisabledReason} presentation={presentation} onResolve={onResolve} - onStartReply={setReplyingGroupId} - onCancelReply={() => setReplyingGroupId(null)} + onStartReply={setReplyingCommentId} + onCancelReply={() => setReplyingCommentId(null)} onReply={onReply} onEditComment={onEditComment} onDeleteComment={onDeleteComment} @@ -2675,13 +2673,13 @@ export function PRCommentsList({ setReplyingGroupId(null)} + onStartReply={setReplyingCommentId} + onCancelReply={() => setReplyingCommentId(null)} onReply={onReply} onEditComment={onEditComment} onDeleteComment={onDeleteComment}