Skip to content
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions backend/conduit/articles/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class Comment(Model, SurrogatePK):
comment_id = Column(db.Integer, db.ForeignKey('comment.id'), nullable=True)
parentComment = relationship('Comment', backref=db.backref('parent', remote_side=[id]), lazy='dynamic')


def __init__(self, article, author, body, comment_id=None, **kwargs):
db.Model.__init__(self, author=author, body=body, article=article, **kwargs)

Expand Down
2 changes: 1 addition & 1 deletion components/article/ArticlePreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const ArticlePreview = ({ article }) => {
if (!isLoggedIn) {
Router.push(`/user/login`);
return;
}
}

setPreview({
...preview,
Expand Down
1 change: 1 addition & 0 deletions components/comment/CommentInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { SERVER_BASE_URL } from "../../lib/utils/constant";
import storage from "../../lib/utils/storage";

const CommentInput = () => {

const { data: currentUser } = useSWR("user", storage);
const isLoggedIn = checkLogin(currentUser);
const router = useRouter();
Expand Down
75 changes: 71 additions & 4 deletions components/comment/CommentList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ import { useRouter } from "next/router";
import React from "react";
import useSWR from "swr";

import { useState } from 'react';
import { message } from 'antd';
import checkLogin from "../../lib/utils/checkLogin";
import storage from "../../lib/utils/storage";
import EditorBox from "./EditorBox";

import CommentInput from "./CommentInput";
import ErrorMessage from "../common/ErrorMessage";
import LoadingSpinner from "../common/LoadingSpinner";
Expand All @@ -11,7 +17,24 @@ import { SERVER_BASE_URL } from "../../lib/utils/constant";
import fetcher from "../../lib/utils/fetcher";
import { Comment, Avatar } from 'antd';


const CommentList = () => {
// clickedComment is the value of the id of the comment that has clicked the Reply To button
var [clickedComment, setClick] = useState( '' );

const { data: currentUser } = useSWR("user", storage);
const isLoggedIn = checkLogin(currentUser)

const handleClickReplyTo = (comment) => {

if (isLoggedIn) {
setClick( comment.id );
}
else { // Not Logged In
message.info("Please log in to reply", 10)
}
}

const router = useRouter();
const {
query: { pid },
Expand All @@ -32,13 +55,35 @@ const CommentList = () => {
);

const { comments } = data;


const recurseComments = (comments) => {
return (

return (

comments.map((comment: CommentType) => (

<Comment
key={comment.id}
actions={[<span key="comment-nested-reply-to">Reply to</span>]}
actions= {[

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the comment is made the editor should close

/*
If the clickedComment has this id, then there is the Editor Box, so hide the Reply To
Else, the clickedComment does NOT have this id,
so show the Reply To option
*/

clickedComment == comment.id ?
null
:
<span key="comment-nested-reply-to"
onClick= {() =>
handleClickReplyTo(comment)
}

>Reply to </span>

]}

author={comment.author.username}
avatar={
<Avatar
Expand All @@ -47,18 +92,40 @@ const CommentList = () => {
/>
}
content={
<p>{comment.body}</p>
<div>
<p>
{ comment.body }
</p>
<p>
{
/*
If the clickedComment has this id, then show the Editor Box
*/
clickedComment == comment.id ?
<EditorBox
commentId = {comment.id}
/> : null
}
</p>

</div>
}
>
{comment.parentComment.comments.length > 0 ? recurseComments(comment.parentComment.comments) : null}

{
comment.parentComment.comments.length > 0 ? recurseComments(comment.parentComment.comments) : null
}

</Comment>

)))
}

return (
<div>
<CommentInput />
{recurseComments(comments)}

</div>
);
};
Expand Down
86 changes: 86 additions & 0 deletions components/comment/EditorBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Based on CommentInput.tsx

import axios from "axios";
import { useRouter } from "next/router";
import React from "react";
import useSWR, { trigger } from "swr";

import checkLogin from "../../lib/utils/checkLogin";
import { SERVER_BASE_URL } from "../../lib/utils/constant";
import storage from "../../lib/utils/storage";


import { Form, Button, Input} from 'antd';
const { TextArea } = Input;


const Editor = ( { onChange, onSubmit, submitting, value } ) => (
<>
<Form.Item>
<TextArea rows={4} onChange={onChange} value={value} />
</Form.Item>
<Form.Item>
<Button htmlType="submit" loading={submitting} onClick={onSubmit} type="primary">
Add Comment
</Button>
</Form.Item>
</>
)

const EditorBox = ( {commentId} ) => {
const { data: currentUser } = useSWR("user", storage);
const isLoggedIn = checkLogin(currentUser);
const router = useRouter();
const {
query: { pid },
} = router;

const [content, setContent] = React.useState("");
const [isLoading, setLoading] = React.useState(false);

const handleChange = React.useCallback((e) => {
setContent(e.target.value);
}, []);

const handleSubmit = async (e) => {
e.preventDefault();
setLoading(true);
await axios.post(
`${SERVER_BASE_URL}/articles/${encodeURIComponent(String(pid))}/comments`,
JSON.stringify({
comment: {
body: content,
comment_id: commentId,
},
}),
{
headers: {
"Content-Type": "application/json",
Authorization: `Token ${encodeURIComponent(currentUser?.token)}`,
},
}
);
setLoading(false);
setContent("");
trigger(`${SERVER_BASE_URL}/articles/${pid}/comments`);
};

if (!isLoggedIn) {
return (
null
);

} else { // is Logged In
return (
<Editor
onChange={handleChange}
onSubmit={ handleSubmit }
submitting = { isLoading }
value={ content }
/>
);
}

};

export default EditorBox;
2 changes: 1 addition & 1 deletion lib/types/commentType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ export type Author = {

export type CommentChildren = {
comments: CommentType[];
}
}
3 changes: 3 additions & 0 deletions pages/article/[pid].tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

import marked from "marked";
import Router, { useRouter } from "next/router";
import React from "react";
Expand All @@ -16,6 +17,7 @@ import CommentList from "../../components/comment/CommentList";
import ArticleAPI from "../../lib/api/article";
import { Article } from "../../lib/types/articleType";
import ArticleTags from "../../components/article/ArticleTags";
import { emitKeypressEvents } from "readline";

const ArticleContain = styled.div`
width: 880px;
Expand Down Expand Up @@ -82,6 +84,7 @@ const ArticlePage = (initialArticle) => {
const { data: currentUser } = useSWR("user", storage);
const isLoggedIn = checkLogin(currentUser);


const handleClickFavorite = async slug => {
if (!isLoggedIn) {
Router.push(`/user/login`);
Expand Down