diff options
| -rw-r--r-- | src/components/Comment/Comment.module.scss | 4 | ||||
| -rw-r--r-- | src/components/Comment/Comment.tsx | 22 | ||||
| -rw-r--r-- | src/services/graphql/queries.ts | 2 | ||||
| -rw-r--r-- | src/ts/types/comments.ts | 1 | ||||
| -rw-r--r-- | src/utils/helpers/format.ts | 31 |
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, |
