feat: enhance comments (#1980)

* feat: non-inline comments support

* enhance comments

* fix types
This commit is contained in:
Philip Okugbe
2026-03-02 01:42:25 +00:00
committed by GitHub
parent d5e4b8bb59
commit 4f3577f009
12 changed files with 310 additions and 184 deletions
@@ -1,6 +1,7 @@
import {
useMutation,
useQueryClient,
InfiniteData,
} from "@tanstack/react-query";
import { resolveComment } from "@/features/comment/services/comment-service";
import {
@@ -10,41 +11,54 @@ import {
import { notifications } from "@mantine/notifications";
import { IPagination } from "@/lib/types.ts";
import { useTranslation } from "react-i18next";
import { useQueryEmit } from "@/features/websocket/use-query-emit";
import { RQ_KEY } from "@/features/comment/queries/comment-query";
function updateCommentInCache(
cache: InfiniteData<IPagination<IComment>>,
commentId: string,
updater: (comment: IComment) => IComment,
): InfiniteData<IPagination<IComment>> {
return {
...cache,
pages: cache.pages.map((page) => ({
...page,
items: page.items.map((comment) =>
comment.id === commentId ? updater(comment) : comment,
),
})),
};
}
export function useResolveCommentMutation() {
const queryClient = useQueryClient();
const { t } = useTranslation();
const emit = useQueryEmit();
return useMutation({
mutationFn: (data: IResolveComment) => resolveComment(data),
onMutate: async (variables) => {
await queryClient.cancelQueries({ queryKey: RQ_KEY(variables.pageId) });
const previousComments = queryClient.getQueryData(RQ_KEY(variables.pageId));
queryClient.setQueryData(RQ_KEY(variables.pageId), (old: IPagination<IComment>) => {
if (!old || !old.items) return old;
const updatedItems = old.items.map((comment) =>
comment.id === variables.commentId
? {
...comment,
resolvedAt: variables.resolved ? new Date() : null,
resolvedById: variables.resolved ? 'optimistic-user' : null,
resolvedBy: variables.resolved ? { id: 'optimistic-user', name: 'Resolving...', avatarUrl: null } : null
}
: comment,
const previousCache = queryClient.getQueryData(RQ_KEY(variables.pageId));
const cache = previousCache as InfiniteData<IPagination<IComment>> | undefined;
if (cache) {
queryClient.setQueryData(
RQ_KEY(variables.pageId),
updateCommentInCache(cache, variables.commentId, (comment) => ({
...comment,
resolvedAt: variables.resolved ? new Date() : null,
resolvedById: variables.resolved ? "optimistic" : null,
resolvedBy: variables.resolved
? { id: "optimistic", name: "", avatarUrl: null }
: null,
})),
);
return {
...old,
items: updatedItems,
};
});
return { previousComments };
}
return { previousCache };
},
onError: (err, variables, context) => {
if (context?.previousComments) {
queryClient.setQueryData(RQ_KEY(variables.pageId), context.previousComments);
onError: (_err, variables, context) => {
if (context?.previousCache) {
queryClient.setQueryData(RQ_KEY(variables.pageId), context.previousCache);
}
notifications.show({
message: t("Failed to resolve comment"),
@@ -52,35 +66,26 @@ export function useResolveCommentMutation() {
});
},
onSuccess: (data: IComment, variables) => {
const pageId = data.pageId;
const currentComments = queryClient.getQueryData(
RQ_KEY(pageId),
) as IPagination<IComment>;
if (currentComments && currentComments.items) {
const updatedComments = currentComments.items.map((comment) =>
comment.id === variables.commentId
? { ...comment, resolvedAt: data.resolvedAt, resolvedById: data.resolvedById, resolvedBy: data.resolvedBy }
: comment,
const cache = queryClient.getQueryData(
RQ_KEY(data.pageId),
) as InfiniteData<IPagination<IComment>> | undefined;
if (cache) {
queryClient.setQueryData(
RQ_KEY(data.pageId),
updateCommentInCache(cache, variables.commentId, (comment) => ({
...comment,
resolvedAt: data.resolvedAt,
resolvedById: data.resolvedById,
resolvedBy: data.resolvedBy,
})),
);
queryClient.setQueryData(RQ_KEY(pageId), {
...currentComments,
items: updatedComments,
});
}
emit({
operation: "resolveComment",
pageId: pageId,
commentId: variables.commentId,
resolved: variables.resolved,
resolvedAt: data.resolvedAt,
resolvedById: data.resolvedById,
resolvedBy: data.resolvedBy,
});
queryClient.invalidateQueries({ queryKey: RQ_KEY(pageId) });
notifications.show({
message: variables.resolved
? t("Comment resolved successfully")
: t("Comment re-opened successfully")
notifications.show({
message: variables.resolved
? t("Comment resolved successfully")
: t("Comment re-opened successfully"),
});
},
});