Skip to content
This repository was archived by the owner on Nov 8, 2022. It is now read-only.

Commit 44f22fa

Browse files
committed
refactor(comments): split comments list into small comps
1 parent 4bc6b4a commit 44f22fa

File tree

14 files changed

+484
-351
lines changed

14 files changed

+484
-351
lines changed

containers/Comments/Actions.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import React from 'react'
2+
3+
import { ICON_CMD } from 'config'
4+
5+
import { Wrapper, ReplyIcon, ReplyAction } from './styles/actions'
6+
import { openUpdateEditor, openReplyEditor, onDelete } from './logic'
7+
8+
const Actions = ({ data, accountInfo }) => {
9+
if (String(data.author.id) === accountInfo.id) {
10+
return (
11+
<Wrapper>
12+
<ReplyAction onClick={openUpdateEditor.bind(this, data)}>
13+
<ReplyIcon src={`${ICON_CMD}/edit.svg`} />
14+
编辑
15+
</ReplyAction>
16+
<ReplyAction onClick={onDelete.bind(this, data)}>
17+
<ReplyIcon src={`${ICON_CMD}/delete.svg`} />
18+
删除
19+
</ReplyAction>
20+
</Wrapper>
21+
)
22+
}
23+
24+
return (
25+
<Wrapper>
26+
<ReplyAction onClick={openReplyEditor.bind(this, data)}>
27+
<ReplyIcon src={`${ICON_CMD}/nest_comment.svg`} />
28+
回复
29+
</ReplyAction>
30+
</Wrapper>
31+
)
32+
}
33+
34+
export default Actions

containers/Comments/Comment.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import React from 'react'
2+
import R from 'ramda'
3+
4+
import { Global } from 'utils'
5+
6+
import MarkDownRender from 'components/MarkDownRender'
7+
8+
import CommentHeader from './CommentHeader'
9+
import CommentReplyBar from './CommentReplyBar'
10+
import DeleteMask from './DeleteMask'
11+
import Reactions from './Reactions'
12+
13+
import {
14+
Wrapper,
15+
CommentWrapper,
16+
CommentUserInfo,
17+
CommentAvatar,
18+
CommentContent,
19+
CommentBodyInfo,
20+
CommentFooter,
21+
} from './styles/comment'
22+
23+
const getSelection = () => {
24+
const selectText = Global.getSelection().toString()
25+
if (!R.isEmpty(selectText)) {
26+
// TODO: then use window.getSelection().getRangeAt(0).getBoundingClientRect() to draw a button
27+
}
28+
}
29+
30+
const Comment = ({ data, tobeDeleteId, accountInfo }) => (
31+
<Wrapper>
32+
<DeleteMask show={data.id === tobeDeleteId} />
33+
<CommentWrapper tobeDelete={data.id === tobeDeleteId}>
34+
<CommentUserInfo>
35+
<CommentAvatar src={data.author.avatar} />
36+
</CommentUserInfo>
37+
38+
<CommentBodyInfo onMouseUp={getSelection}>
39+
<CommentHeader data={data} />
40+
<CommentContent>
41+
{data.replyTo && <CommentReplyBar data={data.replyTo} />}
42+
<MarkDownRender body={data.body} />
43+
</CommentContent>
44+
<CommentFooter>
45+
<Reactions data={data} accountInfo={accountInfo} />
46+
</CommentFooter>
47+
</CommentBodyInfo>
48+
</CommentWrapper>
49+
</Wrapper>
50+
)
51+
52+
export default Comment
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import React from 'react'
2+
import R from 'ramda'
3+
import TimeAgo from 'timeago-react'
4+
5+
// import { ICON_CMD } from '../../config'
6+
// import { Wrapper } from './styles'
7+
8+
import AvatarsRow from 'components/AvatarsRow'
9+
10+
import {
11+
Wrapper,
12+
FloorNum,
13+
CommentAvatar,
14+
MobileAvatar,
15+
HeaderBaseInfo,
16+
CommentUserName,
17+
TimeStamps,
18+
CommentHeaderFirst,
19+
ReplyUsers,
20+
ReplyTitle,
21+
} from './styles/comment_header'
22+
23+
import { previewReply } from './logic'
24+
25+
const getAuthors = comment => {
26+
/* eslint-disable no-return-assign */
27+
const replies = R.forEach(reply => {
28+
return (reply.author.extra_id = reply.id)
29+
}, R.clone(comment.replies))
30+
/* eslint-enable */
31+
32+
return R.pluck('author', replies)
33+
}
34+
35+
const CommentHeader = ({ data }) => (
36+
<Wrapper>
37+
<MobileAvatar>
38+
<CommentAvatar src={data.author.avatar} />
39+
</MobileAvatar>
40+
<HeaderBaseInfo>
41+
<CommentHeaderFirst>
42+
<CommentUserName>
43+
{data.author.nickname}
44+
<FloorNum>#{data.floor}</FloorNum>
45+
</CommentUserName>
46+
{data.repliesCount !== 0 && (
47+
<ReplyUsers>
48+
<ReplyTitle>收到回复:</ReplyTitle>
49+
<AvatarsRow
50+
users={getAuthors(data)}
51+
onUserSelect={previewReply}
52+
total={data.repliesCount}
53+
/>
54+
</ReplyUsers>
55+
)}
56+
</CommentHeaderFirst>
57+
<TimeStamps>
58+
<TimeAgo datetime={data.insertedAt} locale="zh_CN" />
59+
</TimeStamps>
60+
</HeaderBaseInfo>
61+
</Wrapper>
62+
)
63+
64+
export default CommentHeader
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import React from 'react'
2+
3+
import { cutFrom } from 'utils'
4+
import { ReplyBar, ReplyToBody, ReplyToFloor } from './styles/comment_reply_bar'
5+
6+
const CommentReplyBar = ({ data }) => (
7+
<ReplyBar>
8+
回复&nbsp;
9+
{cutFrom(data.author.nickname, 10)}:<ReplyToBody>{data.body}</ReplyToBody>
10+
<ReplyToFloor>#{data.floor}</ReplyToFloor>
11+
</ReplyBar>
12+
)
13+
14+
export default CommentReplyBar

containers/Comments/CommentsList.js

Lines changed: 7 additions & 178 deletions
Original file line numberDiff line numberDiff line change
@@ -1,202 +1,31 @@
1-
import R from 'ramda'
21
import React from 'react'
3-
import TimeAgo from 'timeago-react'
4-
import { Button } from 'antd'
5-
6-
import { ICON_CMD } from 'config'
7-
import { Global, prettyNum, cutFrom } from 'utils'
82

93
import Pagi from 'components/Pagi'
10-
import AvatarsRow from 'components/AvatarsRow'
11-
import { SpaceGrow } from 'components/BaseStyled'
12-
import MarkDownRender from 'components/MarkDownRender'
134

14-
/* import { fakeUsers, getRandomInt, Global, prettyNum } from 'utils' */
155
import { CommentLoading } from 'components/LoadingEffects'
166
import CommentsFilter from './CommentsFilter'
7+
import Comment from './Comment'
178

189
import * as logic from './logic'
1910

20-
// TODO: split
2111
import {
2212
ListsContainer,
2313
ListTitle,
2414
TotalHeader,
2515
TotalCountWrapper,
2616
TotalNum,
27-
FloorNum,
2817
CommentBlock,
29-
CommentWrapper,
30-
DeleteOverlay,
31-
DeleteHintText,
32-
DeleteBtnGroup,
33-
CommentUserInfo,
34-
CommentAvatar,
35-
CommentHeader,
36-
MobileAvatar,
37-
HeaderBaseInfo,
38-
CommentUserName,
39-
TimeStamps,
40-
CommentContent,
41-
CommentBodyInfo,
42-
CommentFooter,
43-
Actions,
44-
VisiableAction,
45-
ReplyIcon,
46-
ReplyAction,
47-
CommentHeaderFirst,
48-
ReplyUsers,
49-
ReplyTitle,
50-
ActionNumber,
51-
UpIcon,
52-
DownIcon,
53-
ReplyBar,
54-
ReplyToBody,
55-
ReplyToFloor,
5618
} from './styles/comments_list'
5719

58-
const getSelection = () => {
59-
const selectText = Global.getSelection().toString()
60-
if (!R.isEmpty(selectText)) {
61-
// TODO: then use window.getSelection().getRangeAt(0).getBoundingClientRect() to draw a button
62-
}
63-
}
64-
65-
const DeleteMask = ({ show }) => (
66-
<DeleteOverlay show={show}>
67-
<DeleteHintText>删除后该该评论将不可恢复</DeleteHintText>
68-
<DeleteBtnGroup>
69-
<Button size="small" type="red" ghost onClick={logic.cancleDelete}>
70-
取消
71-
</Button>
72-
&nbsp;&nbsp;
73-
<Button size="small" type="red" onClick={logic.deleteComment}>
74-
确定删除
75-
</Button>
76-
</DeleteBtnGroup>
77-
</DeleteOverlay>
78-
)
79-
80-
const ActionBottom = ({ data, accountInfo }) => {
81-
if (String(data.author.id) === accountInfo.id) {
82-
return (
83-
<div style={{ display: 'flex' }}>
84-
<ReplyAction onClick={logic.openUpdateEditor.bind(this, data)}>
85-
<ReplyIcon src={`${ICON_CMD}/edit.svg`} />
86-
编辑
87-
</ReplyAction>
88-
<ReplyAction onClick={logic.onDelete.bind(this, data)}>
89-
<ReplyIcon src={`${ICON_CMD}/delete.svg`} />
90-
删除
91-
</ReplyAction>
92-
</div>
93-
)
94-
}
95-
return (
96-
<div style={{ display: 'flex' }}>
97-
<ReplyAction onClick={logic.openReplyEditor.bind(this, data)}>
98-
<ReplyIcon src={`${ICON_CMD}/nest_comment.svg`} />
99-
回复
100-
</ReplyAction>
101-
</div>
102-
)
103-
}
104-
105-
const getAuthors = comment => {
106-
/* eslint-disable no-return-assign */
107-
const replies = R.forEach(reply => {
108-
return (reply.author.extra_id = reply.id)
109-
}, R.clone(comment.replies))
110-
/* eslint-enable */
111-
112-
return R.pluck('author', replies)
113-
}
114-
115-
const Comment = ({ data, tobeDeleteId, accountInfo }) => (
116-
<CommentBlock>
117-
<DeleteMask show={data.id === tobeDeleteId} />
118-
<CommentWrapper tobeDelete={data.id === tobeDeleteId}>
119-
<CommentUserInfo>
120-
<CommentAvatar src={data.author.avatar} />
121-
</CommentUserInfo>
122-
123-
<CommentBodyInfo onMouseUp={getSelection}>
124-
<CommentHeader>
125-
<MobileAvatar>
126-
<CommentAvatar src={data.author.avatar} />
127-
</MobileAvatar>
128-
<HeaderBaseInfo>
129-
<CommentHeaderFirst>
130-
<CommentUserName>
131-
{data.author.nickname}
132-
<FloorNum>#{data.floor}</FloorNum>
133-
</CommentUserName>
134-
{data.repliesCount !== 0 && (
135-
<ReplyUsers>
136-
<ReplyTitle>收到回复:</ReplyTitle>
137-
<AvatarsRow
138-
users={getAuthors(data)}
139-
onUserSelect={logic.previewReply}
140-
total={data.repliesCount}
141-
/>
142-
</ReplyUsers>
143-
)}
144-
</CommentHeaderFirst>
145-
<TimeStamps>
146-
<TimeAgo datetime={data.insertedAt} locale="zh_CN" />
147-
</TimeStamps>
148-
</HeaderBaseInfo>
149-
</CommentHeader>
150-
<CommentContent>
151-
{data.replyTo && (
152-
<ReplyBar>
153-
回复&nbsp;
154-
{cutFrom(data.replyTo.author.nickname, 10)}:
155-
<ReplyToBody>{data.replyTo.body}</ReplyToBody>
156-
<ReplyToFloor>#{data.replyTo.floor}</ReplyToFloor>
157-
</ReplyBar>
158-
)}
159-
<MarkDownRender body={data.body} />
160-
</CommentContent>
161-
<CommentFooter>
162-
<Actions>
163-
<VisiableAction>
164-
<div onClick={logic.toggleLikeComment.bind(this, data)}>
165-
<UpIcon
166-
src={`${ICON_CMD}/up.svg`}
167-
viewerDid={data.viewerHasLiked}
168-
/>
169-
</div>
170-
<ActionNumber>{prettyNum(data.likesCount)}</ActionNumber>
171-
</VisiableAction>
172-
<VisiableAction>
173-
<div onClick={logic.toggleDislikeComment.bind(this, data)}>
174-
<DownIcon
175-
src={`${ICON_CMD}/arrow-up-o.svg`}
176-
viewerDid={data.viewerHasDisliked}
177-
/>
178-
</div>
179-
<ActionNumber>{prettyNum(data.dislikesCount)}</ActionNumber>
180-
</VisiableAction>
181-
<SpaceGrow />
182-
<ActionBottom data={data} accountInfo={accountInfo} />
183-
</Actions>
184-
</CommentFooter>
185-
</CommentBodyInfo>
186-
</CommentWrapper>
187-
</CommentBlock>
188-
)
189-
19020
const Lists = ({ entries, tobeDeleteId, accountInfo }) => (
19121
<React.Fragment>
19222
{entries.map(c => (
193-
<div key={c.id}>
194-
<Comment
195-
data={c}
196-
tobeDeleteId={tobeDeleteId}
197-
accountInfo={accountInfo}
198-
/>
199-
</div>
23+
<Comment
24+
key={c.id}
25+
data={c}
26+
tobeDeleteId={tobeDeleteId}
27+
accountInfo={accountInfo}
28+
/>
20029
))}
20130
</React.Fragment>
20231
)

0 commit comments

Comments
 (0)