|
1 | | -import R from 'ramda' |
2 | 1 | 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' |
8 | 2 |
|
9 | 3 | import Pagi from 'components/Pagi' |
10 | | -import AvatarsRow from 'components/AvatarsRow' |
11 | | -import { SpaceGrow } from 'components/BaseStyled' |
12 | | -import MarkDownRender from 'components/MarkDownRender' |
13 | 4 |
|
14 | | -/* import { fakeUsers, getRandomInt, Global, prettyNum } from 'utils' */ |
15 | 5 | import { CommentLoading } from 'components/LoadingEffects' |
16 | 6 | import CommentsFilter from './CommentsFilter' |
| 7 | +import Comment from './Comment' |
17 | 8 |
|
18 | 9 | import * as logic from './logic' |
19 | 10 |
|
20 | | -// TODO: split |
21 | 11 | import { |
22 | 12 | ListsContainer, |
23 | 13 | ListTitle, |
24 | 14 | TotalHeader, |
25 | 15 | TotalCountWrapper, |
26 | 16 | TotalNum, |
27 | | - FloorNum, |
28 | 17 | 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, |
56 | 18 | } from './styles/comments_list' |
57 | 19 |
|
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 | | - |
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 | | - 回复 |
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 | | - |
190 | 20 | const Lists = ({ entries, tobeDeleteId, accountInfo }) => ( |
191 | 21 | <React.Fragment> |
192 | 22 | {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 | + /> |
200 | 29 | ))} |
201 | 30 | </React.Fragment> |
202 | 31 | ) |
|
0 commit comments