Skip to content

Commit

Permalink
React: Fix caching problems
Browse files Browse the repository at this point in the history
  • Loading branch information
fuma-nama committed Jun 27, 2024
1 parent 9fb8721 commit 13cde81
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 30 deletions.
1 change: 0 additions & 1 deletion packages/prisma-adapter/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ export function createAdapter({ db, getUsers }: Options): StorageAdapter {

return {
id: v.id,
liked: false,
timestamp: v.timestamp,
threadId: v.thread ?? undefined,
page: v.page ?? undefined,
Expand Down
38 changes: 38 additions & 0 deletions packages/react/src/components/avatar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { type HTMLAttributes, type ReactNode } from "react";
import { cn } from "../utils/cn";

interface AvatarProps extends HTMLAttributes<HTMLElement> {
image?: string | null;
placeholder?: string;
}

export function Avatar({
image,
placeholder = "avatar",
...props
}: AvatarProps): ReactNode {
if (image) {
return (
<img
src={image}
alt={placeholder}
{...props}
className={cn(
"size-8 select-none rounded-full bg-fc-muted",
props.className,
)}
/>
);
}

return (
<div
{...props}
aria-label={placeholder}
className={cn(
"size-8 rounded-full bg-gradient-to-br from-blue-600 to-red-600",
props.className,
)}
/>
);
}
6 changes: 5 additions & 1 deletion packages/react/src/components/comment/create-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { buttonVariants } from "../button";
import { CommentEditor, type UseCommentEditor } from "../editor";
import { Spinner } from "../spinner";
import { updateCommentList } from "../../utils/comment-list";
import { syncComments } from "../../utils/comment-manager";

export function CreateForm(): React.ReactElement {
const auth = useAuthContext();
Expand All @@ -31,7 +32,10 @@ export function CreateForm(): React.ReactElement {
}),
{
onSuccess: (data) => {
updateCommentList([data.page, data.threadId], (v) => [data, ...v]);
updateCommentList([data.page, data.threadId], (v) =>
v ? [data, ...v] : undefined,
);
syncComments([data]);
editorRef.current?.commands.clearContent(true);
},
revalidate: false,
Expand Down
10 changes: 7 additions & 3 deletions packages/react/src/components/comment/edit-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ export function EditForm(): React.ReactNode {
thread: comment.threadId,
}),
(_, { arg }: { arg: { id: number; content: object } }) => editComment(arg),
{
revalidate: false,
onSuccess() {
setEdit(false);
},
},
);

const onClose = useLatestCallback(() => {
Expand All @@ -33,10 +39,8 @@ export function EditForm(): React.ReactNode {
void mutation.trigger(
{ id: comment.id, content },
{
revalidate: false,
onSuccess() {
setEdit(false);
updateComment(comment.id, (c) => ({ ...c, content }));
updateComment(comment.id, (item) => ({ ...item, content }));
},
},
);
Expand Down
17 changes: 7 additions & 10 deletions packages/react/src/components/comment/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { MenuTrigger, MenuItems, MenuItem, Menu } from "../menu";
import { buttonVariants } from "../button";
import type { UseCommentEditor } from "../editor";
import { Dialog, DialogContent, DialogTrigger } from "../dialog";
import { Avatar } from "../avatar";
import { EditForm } from "./edit-form";
import { ReplyForm, ReplyHeader } from "./reply-form";
import { ContentRenderer } from "./content-renderer";
Expand Down Expand Up @@ -73,16 +74,12 @@ export function Comment({
data-fc-edit={context.isEditing}
data-fc-reply={context.isReplying}
>
{comment.author.image ? (
<img
alt="avatar"
className="size-8 select-none rounded-full bg-fc-muted"
src={comment.author.image}
/>
) : (
<div className="size-8 rounded-full bg-gradient-to-br from-blue-600 to-red-600" />
)}
<div className="w-0 flex-1">
<Avatar
placeholder={comment.author.name}
image={comment.author.image}
className="shrink-0"
/>
<div className="min-w-0 flex-1 overflow-hidden">
<div className="mb-2 flex flex-row items-center gap-2">
<span className="truncate font-semibold">
{comment.author.name}
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/components/comment/list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const CommentList = forwardRef<HTMLDivElement, CommentListProps>(
([_, options]) => fetchComments(options),
{
onSuccess(data) {
updateCommentList([page, threadId], (v) => [...v, ...data]);
updateCommentList([page, threadId], (v = []) => [...v, ...data]);
syncComments(data);
},
},
Expand Down
9 changes: 5 additions & 4 deletions packages/react/src/components/comment/reply-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { CommentEditor, type UseCommentEditor } from "../editor";
import { Spinner } from "../spinner";
import { DialogTitle } from "../dialog";
import { toLocalString } from "../../utils/date";
import { Avatar } from "../avatar";
import { ContentRenderer } from "./content-renderer";

export function ReplyHeader() {
Expand All @@ -25,10 +26,10 @@ export function ReplyHeader() {
<DialogTitle>Replying to {comment.author.name}</DialogTitle>
<div className="mb-2 flex flex-col gap-4 rounded-xl border border-fc-border p-3 text-sm">
<div className="flex flex-row items-center gap-2 text-xs text-fc-muted-foreground">
<img
alt="avatar"
className="size-6 select-none rounded-full bg-fc-muted"
src={comment.author.image}
<Avatar
className="size-6"
placeholder={comment.author.name}
image={comment.author.image}
/>
<span>{toLocalString(new Date(comment.timestamp))}</span>
</div>
Expand Down
14 changes: 10 additions & 4 deletions packages/react/src/utils/comment-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,18 @@ export function useCommentList(id: KeyArray): SerializedComment[] {

export function updateCommentList(
id: KeyArray,
update: (prev: SerializedComment[]) => SerializedComment[],
update: (
prev: SerializedComment[] | undefined,
) => SerializedComment[] | undefined,
): void {
const key = getKey(id);
const list = data.get(key) ?? [];
data.set(key, update(list));
trigger(key);
const list = data.get(key);
const updated = update(list);

if (updated) {
data.set(key, updated);
trigger(key);
}
}

function getKey(id: KeyArray): string {
Expand Down
16 changes: 10 additions & 6 deletions packages/react/src/utils/comment-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,20 +38,24 @@ export function updateComment(
}

export function onCommentReplied(reply: SerializedComment): void {
updateCommentList([reply.page, reply.threadId], (v) => [reply, ...v]);
updateCommentList([reply.page, reply.threadId], (v) =>
v ? [reply, ...v] : undefined,
);

if (reply.threadId) {
updateComment(reply.threadId, (c) => ({
...c,
replies: c.replies + 1,
}));
updateComment(reply.threadId, (c) => {
console.log(c);

return { ...c, replies: c.replies + 1 };
});
}
}

export function onCommentDeleted(comment: SerializedComment): void {
updateCommentList([comment.page, comment.threadId], (v) =>
v.filter((item) => item.id !== comment.id),
v?.filter((item) => item.id !== comment.id),
);

if (comment.threadId) {
updateComment(comment.threadId, (c) => ({
...c,
Expand Down

0 comments on commit 13cde81

Please sign in to comment.