diff --git a/src/component/CommentForm/index.tsx b/src/component/CommentForm/index.tsx index 13853be..93332a5 100644 --- a/src/component/CommentForm/index.tsx +++ b/src/component/CommentForm/index.tsx @@ -3,7 +3,13 @@ import { Comment, Avatar, Button } from 'antd'; import Markdown from '@/component/Markdown'; const CommentForm: React.FC = (props) => { - const { data, user, onSubmit, onSubmitText = '提交评论' } = props; + const { + data, + user, + onSubmit, + onSubmitText = '提交评论', + extraActions = [], + } = props; const { loginname, avatar_url } = user; const [value, setValue] = useState(''); @@ -33,9 +39,12 @@ const CommentForm: React.FC = (props) => { > {onSubmitText} , + ...extraActions, ]} content={} - /> + > + {props.children} + ); }; @@ -49,4 +58,6 @@ interface Props { }; onSubmit: (value: string) => Promise; onSubmitText?: string; + + extraActions?: React.ReactNode[]; } diff --git a/src/component/CommentList/index.tsx b/src/component/CommentList/index.tsx index f1fc184..7d1cac7 100644 --- a/src/component/CommentList/index.tsx +++ b/src/component/CommentList/index.tsx @@ -1,9 +1,9 @@ import React, { Fragment } from 'react'; import dayjs from 'dayjs'; -import { Link } from 'umi'; +import { Link, useModel } from 'umi'; import Markdown from '@/component/Markdown'; -import { Comment, Avatar, Divider } from 'antd'; +import { Comment, Avatar, Divider, Button } from 'antd'; import { LikeFilled, EditFilled, @@ -12,6 +12,7 @@ import { } from '@ant-design/icons'; import * as styles from './index.less'; +import CommentForm from '@/component/CommentForm'; const unflatten = (array: Node[], parent?: Node, tree?: Node[]) => { let _parent = parent || { id: null, children: [] }; @@ -32,8 +33,18 @@ const unflatten = (array: Node[], parent?: Node, tree?: Node[]) => { }; const CommentList: React.FC = (props) => { - const { list, onLike, onReply, replyRender } = props; + const { + list, + onLike, + onReply, + replyRender, + onEdit, + onDelete, + editComment, + onSubmitEdit, + } = props; const tree = unflatten(list); + const { user } = useModel('user'); const CommentDetail: React.FC<{ data: Node; @@ -41,47 +52,92 @@ const CommentList: React.FC = (props) => { const { id, author, content, create_at, children } = data; const { loginname, avatar_url } = author; + const renderChildren = () => + children?.map((item) => ( + + )); + + const getActions = (): React.ReactNode[] => { + const actions = [ + { + onLike && onLike(data); + }} + />, + ]; + + if (loginname === user?.loginname) { + actions.push( + { + onEdit && onEdit(data); + }} + />, + , + ); + } + + actions.push( + { + onReply && onReply(data); + }} + />, + ); + + return actions; + }; + return ( - { - onLike && onLike(data); - }} - />, - , - , - { - onReply && onReply(data); - }} - />, - ]} - author={{author.loginname}} - datetime={ - {dayjs(create_at).format('YYYY-MM-DD hh:mm:ss')} - } - avatar={ - - - - } - content={ -
- -
- } - > - {replyRender(id)} - - {children?.map((item) => ( - - ))} -
+ {user && editComment && editComment.id === id ? ( + { + onEdit && onEdit(editComment); + }} + > + 取消 + , + ]} + onSubmit={async (values) => { + onSubmitEdit && (await onSubmitEdit(values)); + }} + > + {renderChildren()} + + ) : ( + {loginname}} + datetime={ + {dayjs(create_at).format('YYYY-MM-DD hh:mm:ss')} + } + avatar={ + + + + } + content={ +
+ +
+ } + > + {replyRender(id)} + + {renderChildren()} +
+ )}
); }; @@ -102,10 +158,12 @@ interface Props { onLike?: (record: Node) => void; onEdit?: (record: Node) => void; + onSubmitEdit?: (content: string) => Promise; onReply?: (record: Node) => void; onDelete?: (record: Node) => void; replyRender: (id: string) => React.ReactNode; + editComment?: ReplyModel | null; } interface Node extends ReplyModel { diff --git a/src/page/topic/detail.tsx b/src/page/topic/detail.tsx index 4066dd1..73c70c5 100644 --- a/src/page/topic/detail.tsx +++ b/src/page/topic/detail.tsx @@ -2,7 +2,7 @@ import React, { useState } from 'react'; import { useParams, useModel } from 'umi'; import { useRequest } from 'ahooks'; -import { PageHeader, Divider } from 'antd'; +import { PageHeader, Divider, message } from 'antd'; import * as API from '@/service/topic'; import Markdown from '@/component/Markdown'; @@ -20,6 +20,7 @@ const TopicDetailPage: React.FC> = (props) => { const token = initialState?.token; const [reply, setReply] = useState(); + const [editComment, setEditComment] = useState(); if (!topicId) { return null; @@ -85,6 +86,21 @@ const TopicDetailPage: React.FC> = (props) => { setReply(record); }; + const onEdit = (record: ReplyModel) => { + if (editComment?.id === record.id) { + setEditComment(null); + return; + } + + setEditComment(record); + }; + + const onSubmitEdit = async (content: string) => { + message.info(content); + setEditComment(null); + refresh(); + }; + const renderTopicDetail = () => { if (!data) { return null; @@ -110,7 +126,10 @@ const TopicDetailPage: React.FC> = (props) => { list={replies} onLike={onLike} onReply={onReply} + onEdit={onEdit} replyRender={renderReply} + editComment={editComment} + onSubmitEdit={onSubmitEdit} /> ); };