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
1 change: 1 addition & 0 deletions apps/web/reactCompiledFiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,5 @@ export const REACT_COMPILED_FILES = [
"apps/web/src/components/desktop/SshPasswordPromptDialog.tsx",
"apps/web/src/components/cloud/CloudEnvironmentConnectList.tsx",
"apps/web/src/components/pullRequest/usePullRequestActions.ts",
"apps/web/src/components/pullRequest/PullRequestReviewAnnotation.tsx",
] as const;
76 changes: 38 additions & 38 deletions apps/web/src/components/pullRequest/PullRequestReviewAnnotation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type {
import { HammerIcon, MessageSquareIcon, Trash2Icon } from "lucide-react";
import { Circle, CircleCheck } from "lucide";
import { useRef, useState } from "react";
import { settlePromise, squashAtomCommandFailure } from "@t3tools/client-runtime/state/runtime";

import { formatRelativeTimeLabel } from "~/timestampFormat";
import { cn } from "~/lib/utils";
Expand Down Expand Up @@ -177,42 +178,39 @@ export function ReviewThreadCard({
const trimmed = reply.trim();
if (trimmed.length === 0 || pending || sendingRef.current) return;
sendingRef.current = true;
try {
if (await onReply(trimmed)) {
// The mutation returns no comment. Keep what the reader loaded and reopen its cursor so
// the new reply remains reachable without spending requests until they ask to load it.
setLoadedPage((previous) =>
previous?.threadId === thread.id
? {
...previous,
nextCursor: previous.nextCursor ?? thread.nextCommentsCursor ?? null,
}
: previous,
);
setReply("");
setReplying(false);
}
} finally {
sendingRef.current = false;
}
const result = await settlePromise(() => onReply(trimmed));
sendingRef.current = false;
if (result._tag === "Failure") throw squashAtomCommandFailure(result);
if (!result.value) return;
// The mutation returns no comment. Keep what the reader loaded and reopen its cursor so
// the new reply remains reachable without spending requests until they ask to load it.
setLoadedPage((previous) =>
previous?.threadId === thread.id
? {
...previous,
nextCursor: previous.nextCursor ?? thread.nextCommentsCursor ?? null,
}
: previous,
);
setReply("");
setReplying(false);
};
const loadMore = async () => {
if (nextCommentsCursor === null || loadingMore) return;
setLoadingMore(true);
try {
const page = await onLoadMore(nextCommentsCursor);
if (page === null) return;
setLoadedPage((previous) => ({
threadId: thread.id,
comments: mergePullRequestThreadComments(
previous?.threadId === thread.id ? previous.comments : [],
page.comments,
),
nextCursor: page.nextCursor,
}));
} finally {
setLoadingMore(false);
}
const result = await settlePromise(() => onLoadMore(nextCommentsCursor));
setLoadingMore(false);
if (result._tag === "Failure") throw squashAtomCommandFailure(result);
const page = result.value;
if (page === null) return;
setLoadedPage((previous) => ({
threadId: thread.id,
comments: mergePullRequestThreadComments(
previous?.threadId === thread.id ? previous.comments : [],
page.comments,
),
nextCursor: page.nextCursor,
}));
};

return (
Expand Down Expand Up @@ -332,12 +330,14 @@ export function ReviewThreadCard({
placeholder="Reply"
aria-label="Reply to this conversation"
onChange={(event) => setReply(event.target.value)}
onKeyDown={submitKeys({
value: reply,
pending,
onSubmit: () => void send(),
onCancel: () => setReplying(false),
})}
onKeyDown={(event) =>
submitKeys({
value: reply,
pending,
onSubmit: () => void send(),
onCancel: () => setReplying(false),
})(event)
}
/>
<div className="mt-2 flex justify-end gap-2">
<Button size="xs" variant="ghost" onClick={() => setReplying(false)}>
Expand Down
Loading