Skip to content

Commit 172307b

Browse files
committed
feat: add commnet to topic detail
1 parent fffaa1c commit 172307b

File tree

6 files changed

+166
-20
lines changed

6 files changed

+166
-20
lines changed

src/app.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ const qiankunApps: Array<QiankunApp> = [];
1616

1717
export async function getInitialState(): Promise<InitialState> {
1818
return {
19-
currentUser: 'Suyi',
19+
avatar_url: 'https://avatars.githubusercontent.com/u/958063?v=4&s=120',
20+
loginname: 'thonatos',
2021
};
2122
}
2223

@@ -90,5 +91,6 @@ interface QiankunApp {
9091
}
9192

9293
export interface InitialState {
93-
currentUser: string;
94+
loginname: string;
95+
avatar_url: string;
9496
}

src/global.less

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
width: 100% !important;
77
}
88

9+
.ant-layout-content {
10+
max-width: 100%;
11+
overflow: hidden;
12+
}
13+
914
.cnode-header {
1015
display: flex;
1116
align-items: center;

src/layout.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import React from 'react';
22
import { Link } from 'umi';
33
import { Avatar } from 'antd';
4-
import { UserOutlined } from '@ant-design/icons';
54

65
import {
76
DefaultFooter,
@@ -14,10 +13,13 @@ import { InitialState } from './app';
1413
import config from '../config/basic';
1514
import Brand from './component/Brand';
1615

17-
const RightContent: React.FC<any> = () => {
16+
const RightContent: React.FC<{
17+
data: InitialState;
18+
}> = (props) => {
19+
const { avatar_url } = props.data;
1820
return (
1921
<div className="cnode-header-right">
20-
<Avatar shape="square" size="small" icon={<UserOutlined />} />
22+
<Avatar shape="square" size="small" src={avatar_url} />
2123
</div>
2224
);
2325
};
@@ -77,7 +79,8 @@ const layoutConfig = ({
7779

7880
// right
7981
rightContentRender: () => {
80-
return <RightContent />;
82+
const { avatar_url } = initialState;
83+
return <RightContent data={initialState} />;
8184
},
8285

8386
// footer
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import React from 'react';
2+
import dayjs from 'dayjs';
3+
4+
import { Avatar, Divider, Space } from 'antd';
5+
6+
const SubTitle: React.FC<Props> = (props) => {
7+
const { author, create_at, visit_count, reply_count } = props;
8+
return (
9+
<Space size={0} split={<Divider type="vertical"></Divider>}>
10+
<Avatar size="small" src={author.avatar_url} alt={author.loginname} />
11+
<span>发布:{dayjs(create_at).format('YYYY-MM-DD hh:mm:ss')}</span>
12+
<span>浏览:{visit_count}</span>
13+
<span>回复:{reply_count}</span>
14+
</Space>
15+
);
16+
};
17+
18+
export default SubTitle;
19+
20+
interface Props {
21+
create_at: Date;
22+
reply_count: number;
23+
visit_count: number;
24+
25+
author: {
26+
loginname: string;
27+
avatar_url: string;
28+
};
29+
}

src/page/topic/index.less

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,19 @@
1111
}
1212
}
1313
}
14+
15+
.detail {
16+
}
17+
18+
.comment {
19+
img {
20+
max-width: 100%;
21+
overflow: hidden;
22+
}
23+
}
24+
25+
.comment_content {
26+
* {
27+
overflow: hidden;
28+
}
29+
}

src/page/topic/index.tsx

Lines changed: 105 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,26 @@
11
import React from 'react';
2+
import dayjs from 'dayjs';
3+
24
import { useParams } from 'umi';
35
import { useRequest } from 'ahooks';
4-
import { PageHeader } from 'antd';
6+
import { PageHeader, Comment, Avatar, Divider, Space } from 'antd';
7+
import {
8+
LikeFilled,
9+
EditFilled,
10+
DeleteFilled,
11+
CommentOutlined,
12+
} from '@ant-design/icons';
513
import * as API from '@/service/topic';
614

715
import MarkdownIt from 'markdown-it';
816
import MdEditor from 'react-markdown-editor-lite';
917
import 'react-markdown-editor-lite/lib/index.css';
1018

19+
import SubTitle from './component/SubTitle';
20+
1121
import * as styles from './index.less';
1222

13-
const mdParser = new MarkdownIt(/* Markdown-it options */);
23+
const mdParser = new MarkdownIt();
1424

1525
const TopicDetail: React.FC<React.PropsWithChildren<Props>> = (props) => {
1626
const params: Record<string, any> = useParams();
@@ -42,24 +52,105 @@ const TopicDetail: React.FC<React.PropsWithChildren<Props>> = (props) => {
4252
return null;
4353
}
4454

55+
const renderComment = () => {
56+
if (!data) {
57+
return null;
58+
}
59+
60+
const { replies } = data;
61+
62+
return (
63+
<div className={styles.comment}>
64+
{replies.map((reply: Reply, index: number) => {
65+
const { author, content, create_at } = reply;
66+
return (
67+
<>
68+
{index === replies.length - 1 ? null : (
69+
<Divider type="horizontal" />
70+
)}
71+
72+
<Comment
73+
actions={[
74+
<LikeFilled />,
75+
<EditFilled />,
76+
<DeleteFilled />,
77+
<CommentOutlined />,
78+
]}
79+
author={
80+
<Space size={8}>
81+
<span>{author.loginname}</span>
82+
<span>
83+
{dayjs(create_at).format('YYYY-MM-DD hh:mm:ss')}
84+
</span>
85+
</Space>
86+
}
87+
avatar={
88+
<Avatar src={author.avatar_url} alt={author.loginname} />
89+
}
90+
content={
91+
<div
92+
className={styles.comment_content}
93+
dangerouslySetInnerHTML={{
94+
__html: mdParser.render(content),
95+
}}
96+
></div>
97+
}
98+
></Comment>
99+
</>
100+
);
101+
})}
102+
</div>
103+
);
104+
};
105+
106+
const renderDetail = () => {
107+
if (!data) {
108+
return null;
109+
}
110+
111+
return (
112+
<div className={styles.detail}>
113+
<Divider type="horizontal"></Divider>
114+
<MdEditor
115+
className={styles.editor}
116+
readOnly
117+
view={{
118+
menu: false,
119+
md: false,
120+
html: true,
121+
}}
122+
value={data.content}
123+
renderHTML={(text) => mdParser.render(text)}
124+
// onChange={handleEditorChange}
125+
/>
126+
</div>
127+
);
128+
};
129+
45130
return (
46131
<PageHeader title={data?.title} onBack={() => window.history.back()}>
47-
<MdEditor
48-
className={styles.editor}
49-
readOnly
50-
view={{
51-
menu: false,
52-
md: false,
53-
html: true,
54-
}}
55-
value={data.content}
56-
renderHTML={(text) => mdParser.render(text)}
57-
// onChange={handleEditorChange}
58-
/>
132+
<SubTitle {...data} />
133+
{renderDetail()}
134+
{renderComment()}
59135
</PageHeader>
60136
);
61137
};
62138

63139
export default TopicDetail;
64140

65141
interface Props {}
142+
143+
interface Reply {
144+
id: string;
145+
content: string;
146+
147+
author: {
148+
loginname: string;
149+
avatar_url: string;
150+
};
151+
152+
ups: string[];
153+
create_at: Date;
154+
reply_id?: string;
155+
is_uped: boolean;
156+
}

0 commit comments

Comments
 (0)