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>;