mirror of
https://github.com/wassname/talk.git
synced 2026-09-11 12:51:33 +08:00
feat: added parent/parents edges
This commit is contained in:
@@ -43,7 +43,8 @@ export interface Comment extends TenantResource {
|
||||
status: GQLCOMMENT_STATUS;
|
||||
status_history: StatusHistoryItem[];
|
||||
action_counts: ActionCounts;
|
||||
reply_count: number;
|
||||
grandparent_ids: string[];
|
||||
child_ids: string[];
|
||||
created_at: Date;
|
||||
deleted_at?: Date;
|
||||
metadata?: Record<string, any>;
|
||||
@@ -54,7 +55,8 @@ export type CreateCommentInput = Omit<
|
||||
| "id"
|
||||
| "tenant_id"
|
||||
| "created_at"
|
||||
| "reply_count"
|
||||
// child_ids are always empty for a new comment.
|
||||
| "child_ids"
|
||||
| "body_history"
|
||||
| "status_history"
|
||||
>;
|
||||
@@ -75,7 +77,7 @@ export async function createComment(
|
||||
id: uuid.v4(),
|
||||
tenant_id: tenantID,
|
||||
created_at: now,
|
||||
reply_count: 0,
|
||||
child_ids: [],
|
||||
body_history: [
|
||||
{
|
||||
body,
|
||||
@@ -102,6 +104,32 @@ export async function createComment(
|
||||
return comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* pushChildCommentIDOntoParent will push the new child comment's ID onto the
|
||||
* parent comment so it can reference direct children.
|
||||
*/
|
||||
export async function pushChildCommentIDOntoParent(
|
||||
mongo: Db,
|
||||
tenantID: string,
|
||||
parentID: string,
|
||||
childID: string
|
||||
) {
|
||||
// This pushes the new child ID onto the parent comment.
|
||||
const result = await collection(mongo).findOneAndUpdate(
|
||||
{
|
||||
tenant_id: tenantID,
|
||||
id: parentID,
|
||||
},
|
||||
{
|
||||
$push: {
|
||||
child_ids: childID,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
return result.value;
|
||||
}
|
||||
|
||||
export type EditCommentInput = Pick<
|
||||
Comment,
|
||||
"id" | "author_id" | "body" | "status" | "metadata"
|
||||
@@ -273,6 +301,104 @@ export async function retrieveCommentRepliesConnection(
|
||||
return retrieveConnection(input, query);
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieveCommentParentsConnection will return a comment connection used to
|
||||
* represent the parents of a given comment.
|
||||
*
|
||||
* @param mongo the database connection to use when retrieving comments
|
||||
* @param tenantID the tenant id for where the comment exists
|
||||
* @param commentID the id of the comment to retrieve parents of
|
||||
* @param pagination pagination options to paginate the results
|
||||
*/
|
||||
export async function retrieveCommentParentsConnection(
|
||||
mongo: Db,
|
||||
tenantID: string,
|
||||
comment: Comment,
|
||||
{ last: limit, before: skip = -1 }: { last: number; before?: number }
|
||||
): Promise<Readonly<Connection<Readonly<Comment>>>> {
|
||||
// // Get the base comment, which stores the references to all it's parents.
|
||||
// const comment = await retrieveComment(mongo, tenantID, commentID);
|
||||
// if (!comment) {
|
||||
// throw new Error("comment not found");
|
||||
// }
|
||||
|
||||
// Return nothing if this comment does not have any parents.
|
||||
if (!comment.parent_id) {
|
||||
return {
|
||||
edges: [],
|
||||
pageInfo: {
|
||||
hasNextPage: false,
|
||||
hasPreviousPage: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: (wyattjoh) maybe throw an error when the limit is zero?
|
||||
|
||||
if (limit <= 0) {
|
||||
return {
|
||||
edges: [],
|
||||
pageInfo: {
|
||||
hasNextPage: false,
|
||||
hasPreviousPage: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// If the last paramter is 1, and the after paramter is either unset or equal
|
||||
// to zero, then all we have to return is the direct parent.
|
||||
if (limit === 1 && skip < 0) {
|
||||
const parent = await retrieveComment(mongo, tenantID, comment.parent_id);
|
||||
if (!parent) {
|
||||
throw new Error("parent comment not found");
|
||||
}
|
||||
|
||||
return {
|
||||
edges: nodesToEdges([parent], () => -1),
|
||||
pageInfo: {
|
||||
hasNextPage: false,
|
||||
hasPreviousPage: comment.grandparent_ids.length > 0,
|
||||
endCursor: 0,
|
||||
startCursor: 0,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// Create a list of all the comment parent ids, in reverse order.
|
||||
const parentIDs = [comment.parent_id, ...comment.grandparent_ids.reverse()];
|
||||
|
||||
// Fetch the subset of the comment id's that we are going to query for.
|
||||
const parentIDSubset = parentIDs.slice(skip + 1, skip + 1 + limit);
|
||||
|
||||
// Retrieve the parents via the subset list.
|
||||
const parents = await retrieveManyComments(mongo, tenantID, parentIDSubset);
|
||||
|
||||
// Loop over the list to ensure that none of the entries is null (indicating
|
||||
// that there was a misplaced parent). We can assert the type here because we
|
||||
// will throw an error and abort if one of the comments are null.
|
||||
const nodes = parents.filter(parentComment => {
|
||||
if (!parentComment) {
|
||||
// TODO: (wyattjoh) replace with a better error.
|
||||
throw new Error("parent id specified does not exist");
|
||||
}
|
||||
|
||||
return true;
|
||||
}) as Array<Readonly<Comment>>;
|
||||
|
||||
const edges = nodesToEdges(nodes, (_, index) => index + skip + 1).reverse();
|
||||
|
||||
// Return the resolved connection.
|
||||
return {
|
||||
edges,
|
||||
pageInfo: {
|
||||
hasNextPage: false,
|
||||
hasPreviousPage: parentIDs.length > limit + skip,
|
||||
startCursor: edges.length > 0 ? edges[0].cursor : null,
|
||||
endCursor: edges.length > 0 ? edges[edges.length - 1].cursor : null,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieveAssetConnection returns a Connection<Comment> for a given Asset's
|
||||
* comments.
|
||||
|
||||
Reference in New Issue
Block a user