aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2021-12-27 11:12:47 +0100
committerArmand Philippot <git@armandphilippot.com>2021-12-27 11:12:47 +0100
commit7deed83dbb8835727c743662bee776794d460e74 (patch)
treedb66e3840c42c9c9a6964041d862a9d784ec4410 /src
parentef7912256cb4765d553b002c24b9752c2d5096ac (diff)
chore: display comments as a tree
I was displaying comments without the parent/children link. Now, each child is displayed under its parent. I also remove the reply button for children to avoid too many child depth.
Diffstat (limited to 'src')
-rw-r--r--src/components/Comment/Comment.module.scss4
-rw-r--r--src/components/Comment/Comment.tsx22
-rw-r--r--src/services/graphql/queries.ts2
-rw-r--r--src/ts/types/comments.ts1
-rw-r--r--src/utils/helpers/format.ts31
5 files changed, 51 insertions, 9 deletions
diff --git a/src/components/Comment/Comment.module.scss b/src/components/Comment/Comment.module.scss
index 8f17bfa..46c0249 100644
--- a/src/components/Comment/Comment.module.scss
+++ b/src/components/Comment/Comment.module.scss
@@ -44,6 +44,10 @@
position: relative;
}
+.author {
+ text-align: center;
+}
+
.date {
color: var(--color-fg-secondary);
font-size: var(--font-size-sm);
diff --git a/src/components/Comment/Comment.tsx b/src/components/Comment/Comment.tsx
index ad6875c..7214abe 100644
--- a/src/components/Comment/Comment.tsx
+++ b/src/components/Comment/Comment.tsx
@@ -6,16 +6,22 @@ import Link from 'next/link';
import { useRouter } from 'next/router';
import styles from './Comment.module.scss';
-const Comment = ({ comment }: { comment: CommentData }) => {
+const Comment = ({
+ comment,
+ isNested = false,
+}: {
+ comment: CommentData;
+ isNested?: boolean;
+}) => {
const router = useRouter();
const getCommentAuthor = () => {
return comment.author.url ? (
<Link href={comment.author.url}>
- <a>{comment.author.name}</a>
+ <a className={styles.author}>{comment.author.name}</a>
</Link>
) : (
- <span>{comment.author.name}</span>
+ <span className={styles.author}>{comment.author.name}</span>
);
};
@@ -59,14 +65,16 @@ const Comment = ({ comment }: { comment: CommentData }) => {
className={styles.body}
dangerouslySetInnerHTML={{ __html: comment.content }}
></div>
- <footer className={styles.footer}>
- <Button clickHandler={() => ''}>{t`Reply`}</Button>
- </footer>
+ {!isNested && (
+ <footer className={styles.footer}>
+ <Button clickHandler={() => ''}>{t`Reply`}</Button>
+ </footer>
+ )}
</article>
{comment.replies.length > 0 && (
<ol className={styles.list}>
{comment.replies.map((reply) => {
- return <Comment key={reply.id} comment={reply} />;
+ return <Comment key={reply.id} comment={reply} isNested={true} />;
})}
</ol>
)}
diff --git a/src/services/graphql/queries.ts b/src/services/graphql/queries.ts
index a40446e..1cbb616 100644
--- a/src/services/graphql/queries.ts
+++ b/src/services/graphql/queries.ts
@@ -168,7 +168,7 @@ export const getPostBySlug = async (slug: string): Promise<Article> => {
}
}
commentCount
- comments {
+ comments(where: { order: ASC, orderby: COMMENT_DATE }) {
nodes {
approved
author {
diff --git a/src/ts/types/comments.ts b/src/ts/types/comments.ts
index d5c0052..75e7d23 100644
--- a/src/ts/types/comments.ts
+++ b/src/ts/types/comments.ts
@@ -20,6 +20,7 @@ export type Comment = {
date: string;
id: string;
parentDatabaseId: number;
+ parentId: string | null;
replies: Comment[];
};
diff --git a/src/utils/helpers/format.ts b/src/utils/helpers/format.ts
index fc7f1c2..81bae9c 100644
--- a/src/utils/helpers/format.ts
+++ b/src/utils/helpers/format.ts
@@ -158,6 +158,34 @@ export const getFormattedComments = (rawComments: RawComment[]): Comment[] => {
};
/**
+ * Create a comments tree with replies.
+ * @param comments - A flatten comments list.
+ * @returns An array of comments with replies.
+ */
+export const buildCommentsTree = (comments: Comment[]) => {
+ type CommentsHashTable = {
+ [key: string]: Comment;
+ };
+
+ const hashTable: CommentsHashTable = Object.create(null);
+ const commentsTree: Comment[] = [];
+
+ comments.forEach(
+ (comment) => (hashTable[comment.id] = { ...comment, replies: [] })
+ );
+
+ comments.forEach((comment) => {
+ if (!comment.parentId) {
+ commentsTree.push(hashTable[comment.id]);
+ } else {
+ hashTable[comment.parentId].replies.push(hashTable[comment.id]);
+ }
+ });
+
+ return commentsTree;
+};
+
+/**
* Format an article from RawArticle to Article type.
* @param rawPost - An article coming from WP GraphQL.
* @returns A formatted article.
@@ -183,11 +211,12 @@ export const getFormattedPost = (rawPost: RawArticle): Article => {
};
const formattedComments = getFormattedComments(comments.nodes);
+ const commentsTree = buildCommentsTree(formattedComments);
const formattedPost: Article = {
author: author.node,
commentCount,
- comments: formattedComments,
+ comments: commentsTree,
content: contentParts.afterMore,
databaseId,
dates,