107 lines
2.6 KiB
TypeScript
107 lines
2.6 KiB
TypeScript
import invariant from "invariant";
|
|
import filter from "lodash/filter";
|
|
import orderBy from "lodash/orderBy";
|
|
import { action, runInAction, computed } from "mobx";
|
|
import Comment from "~/models/Comment";
|
|
import Document from "~/models/Document";
|
|
import { PaginationParams } from "~/types";
|
|
import { client } from "~/utils/ApiClient";
|
|
import RootStore from "./RootStore";
|
|
import Store, { RPCAction } from "./base/Store";
|
|
|
|
export default class CommentsStore extends Store<Comment> {
|
|
actions = [
|
|
RPCAction.List,
|
|
RPCAction.Create,
|
|
RPCAction.Update,
|
|
RPCAction.Delete,
|
|
];
|
|
|
|
constructor(rootStore: RootStore) {
|
|
super(rootStore, Comment);
|
|
}
|
|
|
|
/**
|
|
* Returns a list of comments in a document that are not replies to other
|
|
* comments.
|
|
*
|
|
* @param documentId ID of the document to get comments for
|
|
* @returns Array of comments
|
|
*/
|
|
threadsInDocument(documentId: string): Comment[] {
|
|
return this.inDocument(documentId).filter(
|
|
(comment) => !comment.parentCommentId
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Returns a list of comments that are replies to the given comment.
|
|
*
|
|
* @param commentId ID of the comment to get replies for
|
|
* @returns Array of comments
|
|
*/
|
|
inThread(threadId: string): Comment[] {
|
|
return filter(
|
|
this.orderedData,
|
|
(comment) =>
|
|
comment.parentCommentId === threadId || comment.id === threadId
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Returns a list of comments in a document.
|
|
*
|
|
* @param documentId ID of the document to get comments for
|
|
* @returns Array of comments
|
|
*/
|
|
inDocument(documentId: string): Comment[] {
|
|
return filter(
|
|
this.orderedData,
|
|
(comment) => comment.documentId === documentId
|
|
);
|
|
}
|
|
|
|
@action
|
|
setTyping({
|
|
commentId,
|
|
userId,
|
|
}: {
|
|
commentId: string;
|
|
userId: string;
|
|
}): void {
|
|
const comment = this.get(commentId);
|
|
if (comment) {
|
|
comment.typingUsers.set(userId, new Date());
|
|
}
|
|
}
|
|
|
|
@action
|
|
fetchDocumentComments = async (
|
|
documentId: string,
|
|
options?: PaginationParams | undefined
|
|
): Promise<Document[]> => {
|
|
this.isFetching = true;
|
|
|
|
try {
|
|
const res = await client.post(`/comments.list`, {
|
|
documentId,
|
|
...options,
|
|
});
|
|
invariant(res?.data, "Comment list not available");
|
|
|
|
runInAction("CommentsStore#fetchDocumentComments", () => {
|
|
res.data.forEach(this.add);
|
|
this.addPolicies(res.policies);
|
|
});
|
|
return res.data;
|
|
} finally {
|
|
this.isFetching = false;
|
|
}
|
|
};
|
|
|
|
@computed
|
|
get orderedData(): Comment[] {
|
|
return orderBy(Array.from(this.data.values()), "createdAt", "asc");
|
|
}
|
|
}
|