Browse Source

feat: 完成视频评论框大部分功能需求

node 5 years ago
parent
commit
0e1bc13c48

+ 2
- 0
src/App.css View File

@@ -2,6 +2,8 @@
2 2
   width: 100%;
3 3
   padding: 10px;
4 4
   margin-bottom: 100px;
5
+  background: rgba(0, 0, 0, 0.59);
6
+  color: white;
5 7
 }
6 8
 
7 9
 .comment .ant-spin-nested-loading > div > .ant-spin .ant-spin-dot {

+ 4
- 4
src/App.js View File

@@ -463,14 +463,14 @@ class App extends Component {
463 463
       this.state.initDone && (
464 464
         <CommentContext.Provider value={value}>
465 465
           <div className="comment">
466
-            {this.props.showEditor && (
467
-              <CommentInput content={this.props.children} />
468
-            )}
469 466
             {this.props.showList && (
470
-              <div style={{ marginTop: 20 }}>
467
+              <div>
471 468
                 <CommentList />
472 469
               </div>
473 470
             )}
471
+            {this.props.showEditor && (
472
+              <CommentInput content={this.props.children} />
473
+            )}
474 474
           </div>
475 475
         </CommentContext.Provider>
476 476
       )

+ 112
- 24
src/components/CommentBox/index.js View File

@@ -4,6 +4,7 @@ import { Icon } from "antd";
4 4
 import intl from "react-intl-universal";
5 5
 import Comment from "../../Comment";
6 6
 import ContentItem from "./../ContentItem";
7
+import ReplyItem from "./../ReplyItem";
7 8
 import "./index.css";
8 9
 
9 10
 class CommentBox extends Component {
@@ -11,12 +12,14 @@ class CommentBox extends Component {
11 12
     super(props);
12 13
     this.state = {
13 14
       showReply: true,
14
-      page: 1
15
+      page: 1,
16
+      isShowOver3: false
15 17
     };
16 18
 
17 19
     this.handleToggleReply = this.handleToggleReply.bind(this);
18 20
     this.handleGetMoreReply = this.handleGetMoreReply.bind(this);
19 21
     this.renderReplies = this.renderReplies.bind(this);
22
+    this.handleClickCollapse = this.handleClickCollapse.bind(this);
20 23
   }
21 24
 
22 25
   /**
@@ -26,6 +29,14 @@ class CommentBox extends Component {
26 29
     this.setState({ showReply: !this.state.showReply });
27 30
   }
28 31
 
32
+  /**
33
+   * 点击收起按钮的时候只展示最多三条留言
34
+   */
35
+  handleClickCollapse() {
36
+    this.setState({ isShowOver3: !this.state.isShowOver3 });
37
+    console.log("this.isMore", this.state.isShowOver3);
38
+  }
39
+
29 40
   /**
30 41
    * 获取更多评论
31 42
    * @param {string} commentId comment id
@@ -43,56 +54,133 @@ class CommentBox extends Component {
43 54
    * @param {number} replies 回复的数量
44 55
    * @param {boolean} isNoMoreReply 是否没有更多回复
45 56
    */
57
+  // renderReplies(replies, replyCount, isNoMoreReply) {
58
+  //   console.log('replies', replies);
59
+  //   console.log('replyCount', replyCount);
60
+  //   console.log('isNoMoreReply', isNoMoreReply);
61
+  //   const { commentId } = this.props;
62
+  //   const { showReply } = this.state;
63
+  //   if (showReply && replies && replies.length) {
64
+  //     const len = replies.length;
65
+  //     return (
66
+  //       <div style={{ marginLeft: 50 }}>
67
+  //         {replies.map((item, index) => {
68
+  //           if (index === len - 1) {
69
+  //             return [
70
+  //               <ContentItem
71
+  //                 commentId={commentId}
72
+  //                 replyId={item.id}
73
+  //                 key={item.id}
74
+  //                 content={item}
75
+  //                 action="replyToReply" // 回复的回复
76
+  //               />,
77
+  //               <div className="comment-more-box" key="show_more_button">
78
+  //                 {!isNoMoreReply && replyCount !== len && (
79
+  //                   <span
80
+  //                     className="comment-show-more"
81
+  //                     onClick={() => this.handleGetMoreReply(commentId)}
82
+  //                   >
83
+  //                     {intl.get("reply.moreReply")}
84
+  //                   </span>
85
+  //                 )}
86
+
87
+  //                 <a
88
+  //                   style={{ float: "right" }}
89
+  //                   onClick={this.handleToggleReply}
90
+  //                 >
91
+  //                   <Icon type="up" /> {intl.get("reply.collapse")}
92
+  //                 </a>
93
+  //               </div>
94
+  //             ];
95
+  //           }
96
+  //           return (
97
+  //             <ContentItem
98
+  //               commentId={commentId}
99
+  //               replyId={item.id}
100
+  //               key={item.id}
101
+  //               content={item}
102
+  //               action="replyToReply" // 评论的回复
103
+  //             />
104
+  //           );
105
+  //         })}
106
+  //       </div>
107
+  //     );
108
+  //   }
109
+  //   return null;
110
+  // }
111
+
112
+  /**
113
+   * 渲染回复 DOM
114
+   * @param {array} replies 回复列表
115
+   * @param {number} replyCount 回复的数量
116
+   * @param {boolean} isNoMoreReply 是否没有更多回复
117
+   */
46 118
   renderReplies(replies, replyCount, isNoMoreReply) {
119
+    console.log("this.isMore3", this.state.isShowOver3);
47 120
     const { commentId } = this.props;
48 121
     const { showReply } = this.state;
122
+    console.log("replies", replies);
123
+    console.log("replyCount", replyCount);
124
+    console.log("isNoMoreReply", isNoMoreReply);
49 125
     if (showReply && replies && replies.length) {
126
+      console.log("showReply", showReply);
50 127
       const len = replies.length;
51 128
       return (
52
-        <div style={{ marginLeft: 50 }}>
129
+        <div
130
+          style={{
131
+            marginLeft: 50,
132
+            borderTop: "1px solid #e3e3e3",
133
+            paddingTop: 15,
134
+            marginTop: -5
135
+          }}
136
+        >
53 137
           {replies.map((item, index) => {
54 138
             if (index === len - 1) {
55 139
               return [
56
-                <ContentItem
57
-                  commentId={commentId}
58
-                  replyId={item.id}
59
-                  key={item.id}
60
-                  content={item}
61
-                  action="replyToReply" // 回复的回复
62
-                />,
63
-                <div className="comment-more-box" key="show_more_button">
140
+                <ReplyItem replyItem={item} key={item.id} />,
141
+                <div key="show_more_button">
64 142
                   {!isNoMoreReply && replyCount !== len && (
65 143
                     <span
66
-                      className="comment-show-more"
144
+                      // className="comment-show-more"
67 145
                       onClick={() => this.handleGetMoreReply(commentId)}
68 146
                     >
69
-                      {intl.get("reply.moreReply")}
147
+                      展开更多评论
148
+                      <Icon type="down" />
149
+                    </span>
150
+                  )}
151
+                  {replyCount === len && (
152
+                    <span
153
+                      // className="comment-show-more"
154
+                      onClick={() => this.handleClickCollapse()}
155
+                    >
156
+                      收起
157
+                      <Icon type="up" />
70 158
                     </span>
71 159
                   )}
72 160
 
73
-                  <a
161
+                  {/* <a
74 162
                     style={{ float: "right" }}
75 163
                     onClick={this.handleToggleReply}
76 164
                   >
77 165
                     <Icon type="up" /> {intl.get("reply.collapse")}
78
-                  </a>
166
+                  </a> */}
79 167
                 </div>
80 168
               ];
81 169
             }
82
-            return (
83
-              <ContentItem
84
-                commentId={commentId}
85
-                replyId={item.id}
86
-                key={item.id}
87
-                content={item}
88
-                action="replyToReply" // 评论的回复
89
-              />
90
-            );
170
+            if (this.state.isShowOver3) {
171
+              console.log("11111");
172
+              return <ReplyItem replyItem={item} key={item.id} />;
173
+            }
174
+            if (!this.state.isShowOver3 && index < 3) {
175
+              console.log("222222");
176
+              return <ReplyItem replyItem={item} key={item.id} />;
177
+            }
178
+            console.log("3333");
179
+            return null;
91 180
           })}
92 181
         </div>
93 182
       );
94 183
     }
95
-    return null;
96 184
   }
97 185
 
98 186
   render() {

+ 1
- 1
src/components/CommentList/index.js View File

@@ -77,7 +77,7 @@ class CommentList extends Component {
77 77
       <div>
78 78
         <Spin spinning={spinning}>
79 79
           {/* <div>共 {total} 条评论</div> */}
80
-          <div>{intl.get("comment.totalComment", { total })}</div>
80
+          {/* <div>{intl.get("comment.totalComment", { total })}</div> */}
81 81
           {list.map(item => (
82 82
             <CommentBox content={item} key={item.id} commentId={item.id} />
83 83
           ))}

+ 9
- 4
src/components/ContentItem/index.css View File

@@ -1,7 +1,7 @@
1 1
 .comment-item-box {
2 2
   margin: 10px 0 0 0;
3 3
   padding: 15px 5px 0 5px;
4
-  border-top: 1px solid #eee;
4
+  border-top: 1px solid #d5d5d5;
5 5
 }
6 6
 
7 7
 .comment-item-left {
@@ -14,11 +14,11 @@
14 14
   display: inline-block;
15 15
   width: 90%;
16 16
   margin-left: 10px;
17
-  margin-bottom: 20px;
17
+  /* margin-bottom: 20px; */
18 18
 }
19 19
 
20 20
 .comment-item-content {
21
-  margin: 10px 0;
21
+  margin: 10px 0 20px 0;
22 22
   word-break: break-all;
23 23
 }
24 24
 
@@ -38,7 +38,7 @@
38 38
 }
39 39
 
40 40
 .comment-favor {
41
-  font-size: 20px;
41
+  /* font-size: 20px; */
42 42
 }
43 43
 
44 44
 .comment-favored {
@@ -81,6 +81,11 @@
81 81
   margin-right: 10px;
82 82
 }
83 83
 
84
+.comment-item-icon {
85
+  float: right;
86
+  margin-left: 10px;
87
+}
88
+
84 89
 @media screen and (max-width: 616px) and (min-width: 449px) {
85 90
   .comment-item-right {
86 91
     display: inline-block;

+ 49
- 7
src/components/ContentItem/index.js View File

@@ -14,7 +14,7 @@ import { IMAGE_SPLIT } from "../../constant";
14 14
 import "./index.css";
15 15
 import ImagePreviewer from "../ImagePreviewer/ImagePreviewer";
16 16
 
17
-// dayjs.locale("zh-cn");
17
+dayjs.locale("zh-cn");
18 18
 dayjs.extend(relativeTime);
19 19
 
20 20
 const LOCALES = {
@@ -122,8 +122,10 @@ class CommentItem extends Component {
122 122
             {/* <a href={`/${content.user_id}`}>
123 123
               {content.user_name || "暂无昵称"}
124 124
             </a> */}
125
-            <strong>{content.user_name || intl.get("comment.tourist")}</strong>
126
-            <span style={{ marginLeft: 10 }}>
125
+            <strong style={{ color: "#75ACFF" }}>
126
+              {content.user_name || intl.get("comment.tourist")}
127
+            </strong>
128
+            {/* <span style={{ marginLeft: 10 }}>
127 129
               <Tooltip
128 130
                 placement="top"
129 131
                 title={dayjs(content.created * 1000).format(
@@ -136,8 +138,39 @@ class CommentItem extends Component {
136 138
                       .fromNow()
137 139
                   : dayjs(content.created * 1000).fromNow()}
138 140
               </Tooltip>
141
+            </span> */}
142
+            <span
143
+              className="comment-item-icon"
144
+              onClick={this.handleToggleInput}
145
+            >
146
+              <Icon type="message" />
147
+              &nbsp; {content.reply_count}
148
+            </span>
149
+            <span className="comment-item-icon">
150
+              <Icon
151
+                type="heart"
152
+                onClick={() => {
153
+                  if (replyId) {
154
+                    // 如果有 replyId,则说明是评论的回复
155
+                    app.sReplyFavor(content.id, commentId, content.favored);
156
+                    return;
157
+                  }
158
+                  app.sCommentFavor(content.id, content.favored);
159
+                }}
160
+                className={
161
+                  content.favored
162
+                    ? "comment-favor comment-favored"
163
+                    : "comment-favor"
164
+                }
165
+              />
166
+              &nbsp; {content.favor_count}
139 167
             </span>
140 168
           </div>
169
+          <div style={{ color: "#D5D5D5" }}>
170
+            {dayjs(content.created * 1000).format("MM-DD HH:mm:ss")}
171
+          </div>
172
+        </div>
173
+        <div>
141 174
           <div
142 175
             className="comment-item-content"
143 176
             dangerouslySetInnerHTML={{
@@ -194,12 +227,21 @@ class CommentItem extends Component {
194 227
               <div className="clearfix" />
195 228
             </div>
196 229
           )}
197
-          <div className="comment-item-bottom">
230
+          {/* <div className="comment-item-bottom">
231
+            {content.reply_count ? (
232
+              <div>
233
+                <a className="comment-item-bottom-left" onClick={onShowReply}>
234
+                  {content.reply_count} 条回复
235
+                  {showReply ? <Icon type="up" /> : <Icon type="down" />}
236
+                </a>
237
+              </div>
238
+            ) : null}
239
+          </div> */}
240
+          {/* <div className="comment-item-bottom">
198 241
             {content.reply_count ? (
199 242
               <div>
200 243
                 <a className="comment-item-bottom-left" onClick={onShowReply}>
201
-                  {/* {content.reply_count} 条回复 */}
202
-                  {intl.get("reply.totalReply", { total: content.reply_count })}
244
+                  {content.reply_count} 条回复
203 245
                   {showReply ? <Icon type="up" /> : <Icon type="down" />}
204 246
                 </a>
205 247
               </div>
@@ -250,7 +292,7 @@ class CommentItem extends Component {
250 292
               />
251 293
               &nbsp;{content.favor_count}
252 294
             </div>
253
-          </div>
295
+          </div> */}
254 296
         </div>
255 297
 
256 298
         {showInput && (

+ 8
- 0
src/components/Editor/index.css View File

@@ -100,3 +100,11 @@
100 100
 .clearfix {
101 101
   clear: both;
102 102
 }
103
+
104
+.submitBtn {
105
+  width: 88px;
106
+  height: 30px;
107
+  background: rgba(252, 71, 71, 1);
108
+  border-radius: 15px;
109
+  color: #fff;
110
+}

+ 12
- 12
src/components/Editor/index.js View File

@@ -120,8 +120,8 @@ class Editor extends React.Component {
120 120
     const { maxLength } = this.props;
121 121
     let { value, fileMap, fileList } = this.state;
122 122
     if (value.length > maxLength) {
123
-      // message.error(`字数不得超过${maxLength}字`);
124
-      message.error(intl.get("editor.maxLength", { maxLength }));
123
+      message.error(`字数不得超过${maxLength}字`);
124
+      // message.error(intl.get("editor.maxLength", { maxLength }));
125 125
       return;
126 126
     }
127 127
     const files = [];
@@ -183,8 +183,8 @@ class Editor extends React.Component {
183 183
       maxLength,
184 184
       autoFocus
185 185
     } = this.props;
186
-    let placeholder = this.props.placeholder || intl.get("editor.placeholder");
187
-    let btnSubmitText = this.props.placeholder || intl.get("editor.SubmitBtn");
186
+    let placeholder = this.props.placeholder || "快发表评论吧!";
187
+    let btnSubmitText = this.props.placeholder || "发表评论";
188 188
     const handleSubmit = this.handleSubmit;
189 189
     const disabledSubmit =
190 190
       btnDisabled ||
@@ -192,18 +192,14 @@ class Editor extends React.Component {
192 192
     const inputValue = value || this.state.value;
193 193
     return (
194 194
       <div className="comment-editor-container">
195
-        <div
195
+        {/* <div
196 196
           className={classnames({
197 197
             "comment-editor-toolbar": true,
198 198
             "comment-editor-toolbar-error": inputValue.length > maxLength
199 199
           })}
200 200
         >
201
-          {intl.get("editor.alreadyEntered", {
202
-            count: inputValue.length,
203
-            maxLength
204
-          })}
205
-          {/* 已输入 {inputValue.length} / {maxLength} 字 */}
206
-        </div>
201
+          已输入 {inputValue.length} / {maxLength} 字
202
+        </div> */}
207 203
         <div className="comment-editor">
208 204
           <TextArea
209 205
             value={inputValue}
@@ -316,6 +312,9 @@ class Editor extends React.Component {
316 312
             </div>
317 313
 
318 314
             <div className="comment-toolbar-right">
315
+              <span style={{ marginRight: 10 }}>
316
+                {inputValue.length} / {maxLength}
317
+              </span>
319 318
               {button ? (
320 319
                 React.cloneElement(button, {
321 320
                   onClick: button.props.onClick || handleSubmit
@@ -323,7 +322,8 @@ class Editor extends React.Component {
323 322
               ) : (
324 323
                 <Button
325 324
                   onClick={() => this.handleSubmit()}
326
-                  type="primary"
325
+                  // type="primary"
326
+                  className="submitBtn"
327 327
                   loading={btnLoading}
328 328
                   disabled={disabledSubmit}
329 329
                 >

+ 13
- 0
src/components/ReplyItem/index.css View File

@@ -0,0 +1,13 @@
1
+.reply-item {
2
+  margin-bottom: 20px;
3
+  /* margin-top: 5px; */
4
+  color: #d5d5d5;
5
+}
6
+
7
+.reply-item-content {
8
+  margin-bottom: 10px;
9
+}
10
+
11
+.reply-item-span {
12
+  margin-right: 25px;
13
+}

+ 73
- 0
src/components/ReplyItem/index.js View File

@@ -0,0 +1,73 @@
1
+import React, { Component } from "react";
2
+// import PropTypes from 'prop-type';
3
+import { Icon } from "antd";
4
+import Comment from "../../Comment";
5
+import CommentInput from "../CommentInput";
6
+import "./index.css";
7
+
8
+class ReplyItem extends Component {
9
+  constructor(props) {
10
+    super(props);
11
+    this.state = {
12
+      showInput: false
13
+    };
14
+    this.handleToggleInput = this.handleToggleInput.bind(this);
15
+  }
16
+
17
+  handleToggleInput() {
18
+    this.setState({ showInput: !this.state.showInput });
19
+  }
20
+
21
+  render() {
22
+    const { commentId, replyItem, replyId, action, app } = this.props;
23
+
24
+    const { showInput } = this.state;
25
+
26
+    return (
27
+      <div className="reply-item">
28
+        <div className="reply-item-content">
29
+          @<strong>{replyItem.user_name}</strong>
30
+          {replyItem.reply ? ` 回复 @${replyItem.reply.user_name}` : null}:
31
+          &nbsp;
32
+          {replyItem.content}
33
+        </div>
34
+        <div className="reply-item-icon">
35
+          <span className="reply-item-span">
36
+            <Icon
37
+              type="heart"
38
+              onClick={() => {
39
+                if (replyId) {
40
+                  // 如果有 replyId,则说明是评论的回复
41
+                  app.sReplyFavor(replyItem.id, commentId, replyItem.favored);
42
+                  return;
43
+                }
44
+                app.sCommentFavor(replyItem.id, replyItem.favored);
45
+              }}
46
+              className={
47
+                replyItem.favored
48
+                  ? "comment-favor comment-favored"
49
+                  : "comment-favor"
50
+              }
51
+            />
52
+            &nbsp; {replyItem.favor_count}
53
+          </span>
54
+          <span className="reply-item-span">
55
+            <Icon type="message" onClick={this.handleToggleInput} /> &nbsp;{" "}
56
+            {replyItem.reply_count || 0}
57
+          </span>
58
+        </div>
59
+        {showInput && (
60
+          <CommentInput
61
+            content={app.children}
62
+            action={action}
63
+            replyId={replyId}
64
+            commentId={commentId}
65
+            callback={this.handleToggleInput}
66
+          />
67
+        )}
68
+      </div>
69
+    );
70
+  }
71
+}
72
+
73
+export default Comment(ReplyItem);