summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components/Comment/Comment.tsx2
-rw-r--r--src/components/CommentsList/CommentsList.tsx27
-rw-r--r--src/pages/article/[slug].tsx19
-rw-r--r--src/services/graphql/queries.ts60
-rw-r--r--src/ts/types/app.ts5
-rw-r--r--src/ts/types/articles.ts3
-rw-r--r--src/ts/types/comments.ts8
-rw-r--r--src/utils/helpers/format.ts14
8 files changed, 99 insertions, 39 deletions
diff --git a/src/components/Comment/Comment.tsx b/src/components/Comment/Comment.tsx
index 4835f8c..ab1dffc 100644
--- a/src/components/Comment/Comment.tsx
+++ b/src/components/Comment/Comment.tsx
@@ -121,7 +121,7 @@ const Comment = ({
return (
<Comment
articleId={articleId}
- key={reply.id}
+ key={reply.commentId}
comment={reply}
isNested={true}
/>
diff --git a/src/components/CommentsList/CommentsList.tsx b/src/components/CommentsList/CommentsList.tsx
index 6630a03..1e7c3e7 100644
--- a/src/components/CommentsList/CommentsList.tsx
+++ b/src/components/CommentsList/CommentsList.tsx
@@ -1,6 +1,9 @@
import Comment from '@components/Comment/Comment';
+import Spinner from '@components/Spinner/Spinner';
+import { getCommentsByPostId } from '@services/graphql/queries';
import { Comment as CommentData } from '@ts/types/comments';
import { useIntl } from 'react-intl';
+import useSWR from 'swr';
import styles from './CommentsList.module.scss';
const CommentsList = ({
@@ -11,11 +14,29 @@ const CommentsList = ({
comments: CommentData[];
}) => {
const intl = useIntl();
+ const { data, error } = useSWR<CommentData[]>(
+ '/api/comments',
+ () => getCommentsByPostId(articleId),
+ { fallbackData: comments }
+ );
const getCommentsList = () => {
- return comments.map((comment) => {
+ if (error) {
+ return intl.formatMessage({
+ defaultMessage: 'Failed to load.',
+ description: 'CommentsList: failed to load',
+ });
+ }
+
+ if (!data) return <Spinner />;
+
+ return data.map((comment) => {
return (
- <Comment key={comment.id} articleId={articleId} comment={comment} />
+ <Comment
+ key={comment.commentId}
+ articleId={articleId}
+ comment={comment}
+ />
);
});
};
@@ -28,7 +49,7 @@ const CommentsList = ({
description: 'CommentsList: Comments section title',
})}
</h2>
- {comments.length > 0 ? (
+ {data && data.length > 0 ? (
<ol className={styles.list}>{getCommentsList()}</ol>
) : (
<p className={styles['no-comments']}>
diff --git a/src/pages/article/[slug].tsx b/src/pages/article/[slug].tsx
index 7bde448..a0255fa 100644
--- a/src/pages/article/[slug].tsx
+++ b/src/pages/article/[slug].tsx
@@ -6,7 +6,11 @@ import PostHeader from '@components/PostHeader/PostHeader';
import Sidebar from '@components/Sidebar/Sidebar';
import Spinner from '@components/Spinner/Spinner';
import { Sharing, ToC } from '@components/Widgets';
-import { getAllPostsSlug, getPostBySlug } from '@services/graphql/queries';
+import {
+ getAllPostsSlug,
+ getCommentsByPostId,
+ getPostBySlug,
+} from '@services/graphql/queries';
import styles from '@styles/pages/Page.module.scss';
import { NextPageWithLayout } from '@ts/types/app';
import { ArticleMeta, ArticleProps } from '@ts/types/articles';
@@ -25,7 +29,10 @@ import { useIntl } from 'react-intl';
import { Blog, BlogPosting, Graph, WebPage } from 'schema-dts';
import '@utils/plugins/prism-color-scheme';
-const SingleArticle: NextPageWithLayout<ArticleProps> = ({ post }) => {
+const SingleArticle: NextPageWithLayout<ArticleProps> = ({
+ comments,
+ post,
+}) => {
const intl = useIntl();
const router = useRouter();
@@ -47,7 +54,7 @@ const SingleArticle: NextPageWithLayout<ArticleProps> = ({ post }) => {
const {
author,
- comments,
+ commentCount,
content,
databaseId,
dates,
@@ -62,7 +69,7 @@ const SingleArticle: NextPageWithLayout<ArticleProps> = ({ post }) => {
const meta: ArticleMeta = {
author,
- commentCount: comments.length,
+ commentCount: commentCount || undefined,
dates,
readingTime: info.readingTime,
thematics,
@@ -105,7 +112,7 @@ const SingleArticle: NextPageWithLayout<ArticleProps> = ({ post }) => {
description: intro,
articleBody: content,
author: { '@id': `${settings.url}/#branding` },
- commentCount: comments.length,
+ commentCount: commentCount || undefined,
copyrightYear: publicationDate.getFullYear(),
creator: { '@id': `${settings.url}/#branding` },
dateCreated: publicationDate.toISOString(),
@@ -220,11 +227,13 @@ export const getStaticProps: GetStaticProps = async (
const translation = await loadTranslation(locale);
const { slug } = context.params as PostParams;
const post = await getPostBySlug(slug);
+ const comments = await getCommentsByPostId(post.databaseId);
const breadcrumbTitle = post.title;
return {
props: {
breadcrumbTitle,
+ comments,
post,
translation,
},
diff --git a/src/services/graphql/queries.ts b/src/services/graphql/queries.ts
index a9b3141..688d3f2 100644
--- a/src/services/graphql/queries.ts
+++ b/src/services/graphql/queries.ts
@@ -1,6 +1,7 @@
import { Slug } from '@ts/types/app';
import { Article, PostBy, TotalArticles } from '@ts/types/articles';
import { AllPostsSlug, PostsList, RawPostsList } from '@ts/types/blog';
+import { Comment, CommentsByPostId } from '@ts/types/comments';
import {
AllTopics,
AllTopicsSlug,
@@ -18,6 +19,8 @@ import {
getFormattedPostPreview,
getFormattedTopic,
getFormattedThematic,
+ getFormattedComments,
+ buildCommentsTree,
} from '@utils/helpers/format';
import { gql } from 'graphql-request';
import { fetchApi } from './api';
@@ -188,24 +191,6 @@ export const getPostBySlug = async (slug: string): Promise<Article> => {
}
}
commentCount
- comments(where: { order: ASC, orderby: COMMENT_DATE }) {
- nodes {
- approved
- author {
- node {
- gravatarUrl
- name
- url
- }
- }
- commentId
- content
- date
- id
- parentDatabaseId
- parentId
- }
- }
contentParts {
afterMore
beforeMore
@@ -242,7 +227,6 @@ export const getPostBySlug = async (slug: string): Promise<Article> => {
opengraphTitle
opengraphType
opengraphUrl
- readingTime
}
title
}
@@ -255,6 +239,44 @@ export const getPostBySlug = async (slug: string): Promise<Article> => {
};
//==============================================================================
+// Comments query
+//==============================================================================
+
+export const getCommentsByPostId = async (id: number): Promise<Comment[]> => {
+ const query = gql`
+ query MyQuery($id: Int) {
+ postBy(postId: $id) {
+ comments(where: { order: ASC, orderby: COMMENT_DATE }) {
+ nodes {
+ approved
+ author {
+ node {
+ gravatarUrl
+ id
+ name
+ url
+ }
+ }
+ commentId
+ content
+ date
+ parentDatabaseId
+ }
+ }
+ }
+ }
+ `;
+
+ const variables = { id };
+ const response = await fetchApi<CommentsByPostId>(query, variables);
+ const formattedComments = getFormattedComments(
+ response.postBy.comments.nodes
+ );
+
+ return buildCommentsTree(formattedComments);
+};
+
+//==============================================================================
// Topic query
//==============================================================================
diff --git a/src/ts/types/app.ts b/src/ts/types/app.ts
index 3edc8a0..8e087fd 100644
--- a/src/ts/types/app.ts
+++ b/src/ts/types/app.ts
@@ -3,7 +3,7 @@ import { AppProps } from 'next/app';
import { ReactElement, ReactNode } from 'react';
import { PostBy, TotalArticles } from './articles';
import { AllPostsSlug, RawPostsList } from './blog';
-import { CommentData, CreateComment } from './comments';
+import { CommentData, CommentsByPostId, CreateComment } from './comments';
import { ContactData, SendEmail } from './contact';
import {
AllTopics,
@@ -34,6 +34,8 @@ export type VariablesType<T> = T extends PostBy | TopicBy | ThematicBy
? Slug
: T extends RawPostsList
? CursorPagination
+ : T extends CommentsByPostId
+ ? { id: number }
: T extends CreateComment
? CommentData
: T extends SendEmail
@@ -46,6 +48,7 @@ export type RequestType =
| AllTopicsSlug
| AllThematics
| AllThematicsSlug
+ | CommentsByPostId
| CreateComment
| PostBy
| RawPostsList
diff --git a/src/ts/types/articles.ts b/src/ts/types/articles.ts
index 75e5a1a..ea90207 100644
--- a/src/ts/types/articles.ts
+++ b/src/ts/types/articles.ts
@@ -35,7 +35,6 @@ export type ArticleMeta = {
export type Article = {
author: ArticleAuthor;
commentCount: number | null;
- comments: Comment[];
content: string;
databaseId: number;
dates: Dates;
@@ -55,7 +54,6 @@ export type RawArticle = Pick<
> & {
acfPosts: RawACFPosts;
author: { node: ArticleAuthor };
- comments: CommentsNode;
contentParts: ContentParts;
date: string;
featuredImage: RawCover;
@@ -91,6 +89,7 @@ export type PostBy = {
};
export type ArticleProps = {
+ comments: Comment[];
post: Article;
};
diff --git a/src/ts/types/comments.ts b/src/ts/types/comments.ts
index 75e7d23..36bd98c 100644
--- a/src/ts/types/comments.ts
+++ b/src/ts/types/comments.ts
@@ -2,6 +2,14 @@
// Comments query
//==============================================================================
+export type CommentsByPostId = {
+ postBy: {
+ comments: {
+ nodes: RawComment[];
+ };
+ };
+};
+
export type CommentAuthor = {
gravatarUrl: string;
name: string;
diff --git a/src/utils/helpers/format.ts b/src/utils/helpers/format.ts
index 817daaf..9c6f266 100644
--- a/src/utils/helpers/format.ts
+++ b/src/utils/helpers/format.ts
@@ -189,14 +189,16 @@ export const buildCommentsTree = (comments: Comment[]) => {
const commentsTree: Comment[] = [];
comments.forEach(
- (comment) => (hashTable[comment.id] = { ...comment, replies: [] })
+ (comment) => (hashTable[comment.commentId] = { ...comment, replies: [] })
);
comments.forEach((comment) => {
- if (!comment.parentId) {
- commentsTree.push(hashTable[comment.id]);
+ if (!comment.parentDatabaseId) {
+ commentsTree.push(hashTable[comment.commentId]);
} else {
- hashTable[comment.parentId].replies.push(hashTable[comment.id]);
+ hashTable[comment.parentDatabaseId].replies.push(
+ hashTable[comment.commentId]
+ );
}
});
@@ -226,7 +228,6 @@ export const getFormattedPost = (rawPost: RawArticle): Article => {
acfPosts,
author,
commentCount,
- comments,
contentParts,
databaseId,
date,
@@ -243,8 +244,6 @@ export const getFormattedPost = (rawPost: RawArticle): Article => {
update: modified,
};
- const formattedComments = getFormattedComments(comments.nodes);
- const commentsTree = buildCommentsTree(formattedComments);
const topics = acfPosts.postsInTopic
? getFormattedTopicsPreview(acfPosts.postsInTopic)
: [];
@@ -252,7 +251,6 @@ export const getFormattedPost = (rawPost: RawArticle): Article => {
const formattedPost: Article = {
author: author.node,
commentCount,
- comments: commentsTree,
content: contentParts.afterMore,
databaseId,
dates,