forked from farhoodlabs/paperclip
fix(ui): harden issue comment editor sync
This commit is contained in:
@@ -364,6 +364,19 @@ export const MarkdownEditor = forwardRef<MarkdownEditorRef, MarkdownEditorProps>
|
||||
return map;
|
||||
}, [mentions]);
|
||||
|
||||
const setEditorRef = useCallback((instance: MDXEditorMethods | null) => {
|
||||
ref.current = instance;
|
||||
if (!instance) {
|
||||
return;
|
||||
}
|
||||
if (valueRef.current !== latestValueRef.current) {
|
||||
// Re-apply the latest controlled value once MDXEditor exposes its imperative API.
|
||||
echoIgnoreMarkdownRef.current = valueRef.current;
|
||||
instance.setMarkdown(valueRef.current);
|
||||
latestValueRef.current = valueRef.current;
|
||||
}
|
||||
}, []);
|
||||
|
||||
const filteredMentions = useMemo<AutocompleteOption[]>(() => {
|
||||
if (!mentionState) return [];
|
||||
const q = mentionState.query.trim().toLowerCase();
|
||||
@@ -798,7 +811,7 @@ export const MarkdownEditor = forwardRef<MarkdownEditorRef, MarkdownEditorProps>
|
||||
onPasteCapture={handlePasteCapture}
|
||||
>
|
||||
<MDXEditor
|
||||
ref={ref}
|
||||
ref={setEditorRef}
|
||||
markdown={value}
|
||||
placeholder={placeholder}
|
||||
onChange={(next) => {
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
applyOptimisticIssueCommentUpdate,
|
||||
createOptimisticIssueComment,
|
||||
flattenIssueCommentPages,
|
||||
getNextIssueCommentPageParam,
|
||||
isQueuedIssueComment,
|
||||
matchesIssueRef,
|
||||
mergeIssueComments,
|
||||
@@ -171,6 +172,40 @@ describe("optimistic issue comments", () => {
|
||||
expect(flattened.map((comment) => comment.id)).toEqual(["comment-1", "comment-2", "comment-3"]);
|
||||
});
|
||||
|
||||
it("returns no next page param when the last page is missing", () => {
|
||||
expect(getNextIssueCommentPageParam(undefined, 50)).toBeUndefined();
|
||||
});
|
||||
|
||||
it("returns the oldest id when the last page is full", () => {
|
||||
expect(
|
||||
getNextIssueCommentPageParam(
|
||||
[
|
||||
{
|
||||
id: "comment-2",
|
||||
companyId: "company-1",
|
||||
issueId: "issue-1",
|
||||
authorAgentId: null,
|
||||
authorUserId: "board-1",
|
||||
body: "Second",
|
||||
createdAt: new Date("2026-03-28T14:00:02.000Z"),
|
||||
updatedAt: new Date("2026-03-28T14:00:02.000Z"),
|
||||
},
|
||||
{
|
||||
id: "comment-1",
|
||||
companyId: "company-1",
|
||||
issueId: "issue-1",
|
||||
authorAgentId: null,
|
||||
authorUserId: "board-1",
|
||||
body: "First",
|
||||
createdAt: new Date("2026-03-28T14:00:01.000Z"),
|
||||
updatedAt: new Date("2026-03-28T14:00:01.000Z"),
|
||||
},
|
||||
],
|
||||
2,
|
||||
),
|
||||
).toBe("comment-1");
|
||||
});
|
||||
|
||||
it("upserts paged comments without dropping older pages", () => {
|
||||
const nextPages = upsertIssueCommentInPages(
|
||||
[
|
||||
|
||||
@@ -102,6 +102,14 @@ export function flattenIssueCommentPages(
|
||||
return sortIssueComments((pages ?? []).flatMap((page) => page));
|
||||
}
|
||||
|
||||
export function getNextIssueCommentPageParam(
|
||||
lastPage: ReadonlyArray<IssueComment> | undefined,
|
||||
pageSize: number,
|
||||
): string | undefined {
|
||||
if (!lastPage || lastPage.length < pageSize) return undefined;
|
||||
return lastPage[lastPage.length - 1]?.id;
|
||||
}
|
||||
|
||||
export function upsertIssueComment(
|
||||
comments: IssueComment[] | undefined,
|
||||
nextComment: IssueComment,
|
||||
|
||||
@@ -36,6 +36,7 @@ import {
|
||||
applyOptimisticIssueCommentUpdate,
|
||||
createOptimisticIssueComment,
|
||||
flattenIssueCommentPages,
|
||||
getNextIssueCommentPageParam,
|
||||
isQueuedIssueComment,
|
||||
matchesIssueRef,
|
||||
mergeIssueComments,
|
||||
@@ -416,7 +417,7 @@ export function IssueDetail() {
|
||||
enabled: !!issueId,
|
||||
initialPageParam: null as string | null,
|
||||
getNextPageParam: (lastPage) =>
|
||||
lastPage.length === ISSUE_COMMENT_PAGE_SIZE ? lastPage[lastPage.length - 1]?.id : undefined,
|
||||
getNextIssueCommentPageParam(lastPage, ISSUE_COMMENT_PAGE_SIZE),
|
||||
placeholderData: keepPreviousData,
|
||||
});
|
||||
const comments = useMemo(
|
||||
|
||||
Reference in New Issue
Block a user