Sfoglia il codice sorgente

feature: 评论移动端初适配

cloudzqy 6 anni fa
parent
commit
b81225284a

+ 3
- 0
src/App.js Vedi File

@@ -411,6 +411,8 @@ class App extends Component {
411 411
       sDeleteReply: this.sDeleteReply
412 412
     };
413 413
 
414
+    console.log(this.props.isMobile);
415
+
414 416
     return (
415 417
       <CommentContext.Provider value={value}>
416 418
         <div className="comment">
@@ -445,6 +447,7 @@ App.propTypes = {
445 447
   limit: PropTypes.number, // 一次加载评论数量
446 448
   onPageChange: PropTypes.func, // 页码变化回调
447 449
   onGetMoreBtnClick: PropTypes.func, // 点击查看更多按钮回调
450
+  isMobile: PropTypes.bool,
448 451
   onDelete: PropTypes.func
449 452
 };
450 453
 

+ 14
- 11
src/components/CommentBox/index.js Vedi File

@@ -43,7 +43,7 @@ class CommentBox extends Component {
43 43
    * @param {boolean} isNoMoreReply 是否没有更多回复
44 44
    */
45 45
   renderReplies(replies, replyCount, isNoMoreReply) {
46
-    const { commentId } = this.props;
46
+    const { commentId, isMobile } = this.props;
47 47
     const { showReply } = this.state;
48 48
     if (showReply && replies && replies.length) {
49 49
       const len = replies.length;
@@ -54,21 +54,21 @@ class CommentBox extends Component {
54 54
               return [
55 55
                 <ContentItem
56 56
                   commentId={commentId}
57
+                  isMobile={isMobile}
57 58
                   replyId={item.id}
58 59
                   key={item.id}
59 60
                   content={item}
60 61
                   action="replyToReply" // 回复的回复
61 62
                 />,
62 63
                 <div className="comment-more-box" key="show_more_button">
63
-                  {!isNoMoreReply &&
64
-                    replyCount !== len && (
65
-                      <span
66
-                        className="comment-show-more"
67
-                        onClick={() => this.handleGetMoreReply(commentId)}
68
-                      >
69
-                        查看更多回复
70
-                      </span>
71
-                    )}
64
+                  {!isNoMoreReply && replyCount !== len && (
65
+                    <span
66
+                      className="comment-show-more"
67
+                      onClick={() => this.handleGetMoreReply(commentId)}
68
+                    >
69
+                      查看更多回复
70
+                    </span>
71
+                  )}
72 72
 
73 73
                   <a
74 74
                     style={{ float: "right" }}
@@ -81,6 +81,7 @@ class CommentBox extends Component {
81 81
             }
82 82
             return (
83 83
               <ContentItem
84
+                isMobile={isMobile}
84 85
                 commentId={commentId}
85 86
                 replyId={item.id}
86 87
                 key={item.id}
@@ -96,11 +97,13 @@ class CommentBox extends Component {
96 97
   }
97 98
 
98 99
   render() {
99
-    const { content } = this.props;
100
+    const { content, isMobile } = this.props;
100 101
     const { showReply } = this.state;
102
+
101 103
     return (
102 104
       <div>
103 105
         <ContentItem
106
+          isMobile={isMobile}
104 107
           content={content}
105 108
           onShowReply={this.handleToggleReply}
106 109
           showReply={showReply}

+ 7
- 2
src/components/CommentList/index.js Vedi File

@@ -67,7 +67,7 @@ class CommentList extends Component {
67 67
   }
68 68
 
69 69
   render() {
70
-    const { list, total, loading } = this.props.app;
70
+    const { list, total, loading, isMobile } = this.props.app;
71 71
 
72 72
     const spinning = Boolean(
73 73
       loading.sGetComment || loading.sCommentFavor || loading.sReplyFavor
@@ -77,7 +77,12 @@ class CommentList extends Component {
77 77
         <Spin spinning={spinning}>
78 78
           <div>共 {total} 条评论</div>
79 79
           {list.map(item => (
80
-            <CommentBox content={item} key={item.id} commentId={item.id} />
80
+            <CommentBox
81
+              isMobile={isMobile}
82
+              content={item}
83
+              key={item.id}
84
+              commentId={item.id}
85
+            />
81 86
           ))}
82 87
           {this.renderPagination()}
83 88
         </Spin>

+ 21
- 7
src/components/ContentItem/index.css Vedi File

@@ -10,18 +10,28 @@
10 10
   width: 40px;
11 11
 }
12 12
 
13
-.comment-item-right {
13
+.comment-item-middle {
14 14
   display: inline-block;
15
-  width: 90%;
15
+  width: 80%;
16 16
   margin-left: 10px;
17 17
   margin-bottom: 20px;
18 18
 }
19 19
 
20
+.comment-item-right {
21
+  display: inline-block;
22
+  vertical-align: top;
23
+  width: 10%;
24
+}
25
+
20 26
 .comment-item-content {
21 27
   margin: 10px 0;
22 28
   word-break: break-all;
23 29
 }
24 30
 
31
+.comment-item-top-right {
32
+  margin: 20px auto;
33
+}
34
+
25 35
 .comment-item-bottom {
26 36
   margin: 20px auto;
27 37
 }
@@ -81,8 +91,12 @@
81 91
   margin-right: 10px;
82 92
 }
83 93
 
94
+.text-center {
95
+  text-align: center;
96
+}
97
+
84 98
 @media screen and (max-width: 616px) and (min-width: 449px) {
85
-  .comment-item-right {
99
+  .comment-item-middle {
86 100
     display: inline-block;
87 101
     width: 85%;
88 102
     margin-left: 10px;
@@ -90,17 +104,17 @@
90 104
 }
91 105
 
92 106
 @media screen and (max-width: 449px) and (min-width: 365px) {
93
-  .comment-item-right {
107
+  .comment-item-middle {
94 108
     display: inline-block;
95
-    width: 80%;
109
+    width: 70%;
96 110
     margin-left: 10px;
97 111
   }
98 112
 }
99 113
 
100 114
 @media screen and (max-width: 365px) {
101
-  .comment-item-right {
115
+  .comment-item-middle {
102 116
     display: inline-block;
103
-    width: 75%;
117
+    width: 65%;
104 118
     margin-left: 10px;
105 119
   }
106 120
 }

+ 174
- 32
src/components/ContentItem/index.js Vedi File

@@ -75,6 +75,7 @@ class CommentItem extends Component {
75 75
       action,
76 76
       showReply,
77 77
       onShowReply,
78
+      isMobile,
78 79
       app
79 80
     } = this.props;
80 81
 
@@ -105,39 +106,26 @@ class CommentItem extends Component {
105 106
       }
106 107
     }
107 108
 
108
-    return (
109
-      <div className="comment-item-box">
110
-        <div className="comment-item-left">
111
-          <Avatar src={content.user_avatar || avatar} size="large" />
112
-        </div>
113
-        <div className="comment-item-right">
114
-          <div>
115
-            {/* <a href={`/${content.user_id}`}>
116
-              {content.user_name || "暂无昵称"}
117
-            </a> */}
118
-            <strong>{content.user_name || "游客"}</strong>
119
-            <span style={{ marginLeft: 10 }}>
120
-              <Tooltip
121
-                placement="top"
122
-                title={dayjs(content.created * 1000).format(
123
-                  "YYYY-MM-DD HH:mm:ss"
124
-                )}
125
-              >
126
-                {dayjs(content.created * 1000).fromNow()}
127
-              </Tooltip>
128
-            </span>
109
+    if (isMobile) {
110
+      return (
111
+        <div className="comment-item-box">
112
+          <div className="comment-item-left">
113
+            <Avatar src={content.user_avatar || avatar} size="large" />
129 114
           </div>
130
-          <div
131
-            className="comment-item-content"
132
-            dangerouslySetInnerHTML={{
133
-              __html: renderContent(
134
-                this.renderTextWithReply(newContent, content)
135
-              )
136
-            }}
137
-          />
138
-          {// image为空时不渲染comment-item-image
139
-          imageList.length > 0 &&
140
-            imageList[0] !== "" && (
115
+          <div className="comment-item-middle">
116
+            <div>
117
+              <strong>{content.user_name || "游客"}</strong>
118
+            </div>
119
+            <div
120
+              className="comment-item-content"
121
+              dangerouslySetInnerHTML={{
122
+                __html: renderContent(
123
+                  this.renderTextWithReply(newContent, content)
124
+                )
125
+              }}
126
+            />
127
+            {// image为空时不渲染comment-item-image
128
+            imageList.length > 0 && imageList[0] !== "" && (
141 129
               <div className="comment-item-image">
142 130
                 {!this.state.showPreviewer &&
143 131
                   imgs.map((item, index) => {
@@ -184,6 +172,160 @@ class CommentItem extends Component {
184 172
                 <div className="clearfix" />
185 173
               </div>
186 174
             )}
175
+            <div>
176
+              <Tooltip
177
+                placement="top"
178
+                title={dayjs(content.created * 1000).format(
179
+                  "YYYY-MM-DD HH:mm:ss"
180
+                )}
181
+              >
182
+                {dayjs(content.created * 1000).fromNow()}
183
+              </Tooltip>
184
+            </div>
185
+            <div className="comment-item-bottom">
186
+              {content.reply_count ? (
187
+                <div>
188
+                  <a className="comment-item-bottom-left" onClick={onShowReply}>
189
+                    {content.reply_count} 条回复
190
+                    {showReply ? <Icon type="up" /> : <Icon type="down" />}
191
+                  </a>
192
+                </div>
193
+              ) : null}
194
+              {app.userId === content.user_id && (
195
+                <Popconfirm
196
+                  title="确定要删除吗?"
197
+                  onConfirm={() => {
198
+                    if (replyId) {
199
+                      app.sDeleteReply(content.id, commentId);
200
+                      return;
201
+                    }
202
+                    app.sDeleteComment(content.id);
203
+                  }}
204
+                  okText="确定"
205
+                  cancelText="取消"
206
+                >
207
+                  <a className="comment-item-bottom-right">&nbsp; 删除</a>
208
+                </Popconfirm>
209
+              )}
210
+            </div>
211
+          </div>
212
+
213
+          <div className="comment-item-right">
214
+            <div
215
+              className="comment-item-top-right"
216
+              onClick={() => {
217
+                if (replyId) {
218
+                  // 如果有 replyId,则说明是评论的回复
219
+                  app.sReplyFavor(content.id, commentId, content.favored);
220
+                  return;
221
+                }
222
+                app.sCommentFavor(content.id, content.favored);
223
+              }}
224
+            >
225
+              <div className="text-center">
226
+                <Icon
227
+                  type="heart"
228
+                  className={
229
+                    content.favored
230
+                      ? "comment-favor comment-favored"
231
+                      : "comment-favor"
232
+                  }
233
+                />
234
+              </div>
235
+              <div className="text-center">{content.favor_count}</div>
236
+            </div>
237
+          </div>
238
+          {showInput && (
239
+            <CommentInput
240
+              content={app.children}
241
+              action={action}
242
+              replyId={replyId}
243
+              commentId={commentId}
244
+              callback={this.handleToggleInput}
245
+            />
246
+          )}
247
+        </div>
248
+      );
249
+    }
250
+
251
+    return (
252
+      <div className="comment-item-box">
253
+        <div className="comment-item-left">
254
+          <Avatar src={content.user_avatar || avatar} size="large" />
255
+        </div>
256
+        <div className="comment-item-right">
257
+          <div>
258
+            {/* <a href={`/${content.user_id}`}>
259
+              {content.user_name || "暂无昵称"}
260
+            </a> */}
261
+            <strong>{content.user_name || "游客"}</strong>
262
+            <span style={{ marginLeft: 10 }}>
263
+              <Tooltip
264
+                placement="top"
265
+                title={dayjs(content.created * 1000).format(
266
+                  "YYYY-MM-DD HH:mm:ss"
267
+                )}
268
+              >
269
+                {dayjs(content.created * 1000).fromNow()}
270
+              </Tooltip>
271
+            </span>
272
+          </div>
273
+          <div
274
+            className="comment-item-content"
275
+            dangerouslySetInnerHTML={{
276
+              __html: renderContent(
277
+                this.renderTextWithReply(newContent, content)
278
+              )
279
+            }}
280
+          />
281
+          {// image为空时不渲染comment-item-image
282
+          imageList.length > 0 && imageList[0] !== "" && (
283
+            <div className="comment-item-image">
284
+              {!this.state.showPreviewer &&
285
+                imgs.map((item, index) => {
286
+                  if (item.type === "divider") {
287
+                    return (
288
+                      <div className="comment-item-image-wrapper" key={index}>
289
+                        <div className="comment-img-divider" />
290
+                        {/* <img src={item} alt={item} className="comment-img" /> */}
291
+                      </div>
292
+                    );
293
+                  }
294
+                  return (
295
+                    <div
296
+                      className="comment-item-image-wrapper"
297
+                      key={index}
298
+                      onClick={() => {
299
+                        let i = index;
300
+                        if (needClear) {
301
+                          if (index > 3) {
302
+                            i -= 1;
303
+                          }
304
+                          if (index > 7) {
305
+                            i -= 1;
306
+                          }
307
+                        }
308
+                        this.showPreviewer(i);
309
+                      }}
310
+                    >
311
+                      <div
312
+                        style={{ backgroundImage: `url(${item})` }}
313
+                        className="comment-img-thumbnail"
314
+                      />
315
+                      {/* <img src={item} alt={item} className="comment-img" /> */}
316
+                    </div>
317
+                  );
318
+                })}
319
+              {this.state.showPreviewer && (
320
+                <ImagePreviewer
321
+                  list={imageList}
322
+                  index={this.state.previewerIndex}
323
+                  onFold={this.hidePreviewer}
324
+                />
325
+              )}
326
+              <div className="clearfix" />
327
+            </div>
328
+          )}
187 329
           <div className="comment-item-bottom">
188 330
             {content.reply_count ? (
189 331
               <div>

+ 8
- 1
src/index.js Vedi File

@@ -4,7 +4,14 @@ import App, { Editor } from "./App";
4 4
 // import registerServiceWorker from "./registerServiceWorker";
5 5
 
6 6
 const Index = props => (
7
-  <App showAlertComment showAlertReply showAlertFavor showError {...props}>
7
+  <App
8
+    isMobile
9
+    showAlertComment
10
+    showAlertReply
11
+    showAlertFavor
12
+    showError
13
+    {...props}
14
+  >
8 15
     <Editor maxUpload={9} autoFocus />
9 16
   </App>
10 17
 );