File size: 1,843 Bytes
561e6f0 76fc93a 561e6f0 76fc93a 561e6f0 76fc93a 561e6f0 76fc93a 561e6f0 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | import * as Y from "yjs";
export interface ReplyData {
id: string;
author: string;
authorColor: string;
text: string;
createdAt: number;
}
export interface CommentData {
id: string;
author: string;
authorColor: string;
text: string;
createdAt: number;
resolved: boolean;
resolvedBy?: string;
resolvedAt?: number;
replies: ReplyData[];
}
export function createCommentStore(ydoc: Y.Doc) {
const ymap = ydoc.getMap<CommentData>("comments");
return {
add(comment: Omit<CommentData, "replies">) {
ymap.set(comment.id, { ...comment, replies: [] });
},
addReply(commentId: string, reply: ReplyData) {
const comment = ymap.get(commentId);
if (!comment) return;
ymap.set(commentId, {
...comment,
replies: [...comment.replies, reply],
});
},
resolve(id: string, resolvedBy: string) {
const comment = ymap.get(id);
if (!comment) return;
ymap.set(id, {
...comment,
resolved: true,
resolvedBy,
resolvedAt: Date.now(),
});
},
unresolve(id: string) {
const comment = ymap.get(id);
if (!comment) return;
ymap.set(id, {
...comment,
resolved: false,
resolvedBy: undefined,
resolvedAt: undefined,
});
},
remove(id: string) {
ymap.delete(id);
},
get(id: string): CommentData | undefined {
return ymap.get(id);
},
getAll(): CommentData[] {
const comments: CommentData[] = [];
ymap.forEach((value) => comments.push(value));
return comments.sort((a, b) => a.createdAt - b.createdAt);
},
observe(callback: () => void) {
ymap.observe(callback);
return () => ymap.unobserve(callback);
},
};
}
export type CommentStore = ReturnType<typeof createCommentStore>;
|