Browse Source

add:头像添加hover和点击效果

zhengyingya 5 years ago
parent
commit
b379c19830

+ 5
- 2
.babelrc View File

2
   "presets": ["env", "react"],
2
   "presets": ["env", "react"],
3
   "plugins": [
3
   "plugins": [
4
     "transform-object-rest-spread",
4
     "transform-object-rest-spread",
5
-    ["import", { "libraryName": "antd", "libraryDirectory": "es", "style": "css" }]
5
+    [
6
+      "import",
7
+      { "libraryName": "antd", "libraryDirectory": "es", "style": "css" }
8
+    ]
6
   ]
9
   ]
7
-}
10
+}

+ 5
- 1
lib/components/CommentBox/index.js View File

114
                 replyId: item.id,
114
                 replyId: item.id,
115
                 key: item.id,
115
                 key: item.id,
116
                 content: item,
116
                 content: item,
117
+                user_id: item.user_id,
117
                 action: "replyToReply" // 回复的回复
118
                 action: "replyToReply" // 回复的回复
118
               }), _react2.default.createElement(
119
               }), _react2.default.createElement(
119
                 "div",
120
                 "div",
155
   }, {
156
   }, {
156
     key: "render",
157
     key: "render",
157
     value: function render() {
158
     value: function render() {
158
-      var content = this.props.content;
159
+      var _props = this.props,
160
+          content = _props.content,
161
+          user_id = _props.user_id;
159
       var showReply = this.state.showReply;
162
       var showReply = this.state.showReply;
160
 
163
 
161
       return _react2.default.createElement(
164
       return _react2.default.createElement(
166
           onShowReply: this.handleToggleReply,
169
           onShowReply: this.handleToggleReply,
167
           showReply: showReply,
170
           showReply: showReply,
168
           commentId: content.id,
171
           commentId: content.id,
172
+          user_id: user_id,
169
           action: "reply" // 评论的回复
173
           action: "reply" // 评论的回复
170
         }),
174
         }),
171
         this.renderReplies(content.replies, content.reply_count, content.isNoMoreReply)
175
         this.renderReplies(content.replies, content.reply_count, content.isNoMoreReply)

+ 1
- 1
lib/components/CommentBox/index.js.map
File diff suppressed because it is too large
View File


+ 6
- 1
lib/components/CommentList/index.js View File

144
             _reactIntlUniversal2.default.get("comment.totalComment", { total: total })
144
             _reactIntlUniversal2.default.get("comment.totalComment", { total: total })
145
           ),
145
           ),
146
           list.map(function (item) {
146
           list.map(function (item) {
147
-            return _react2.default.createElement(_CommentBox2.default, { content: item, key: item.id, commentId: item.id });
147
+            return _react2.default.createElement(_CommentBox2.default, {
148
+              content: item,
149
+              user_id: item.user_id,
150
+              key: item.id,
151
+              commentId: item.id
152
+            });
148
           }),
153
           }),
149
           this.renderPagination()
154
           this.renderPagination()
150
         )
155
         )

+ 1
- 1
lib/components/CommentList/index.js.map View File

1
-{"version":3,"sources":["../../../src/components/CommentList/index.js"],"names":["CommentList","props","state","app","sGetComment","page","list","total","pageType","limit","isNoMoreComment","onPageChange","onGetMoreBtnClick","length","intl","get","p","loading","spinning","Boolean","sCommentFavor","sReplyFavor","map","item","id","renderPagination","Component","propTypes"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;;;;AAEA;;;;AACA;;;;AACA;;;;AACA;;;;;;;;;;IAEMA,W;;;AACJ,uBAAYC,KAAZ,EAAmB;AAAA;;AAAA,0HACXA,KADW;;AAEjB,UAAKC,KAAL,GAAa,EAAb;AAFiB;AAGlB;;;;yCAEoB;AACnB,WAAKD,KAAL,CAAWE,GAAX,CAAeC,WAAf,CAA2B,EAAEC,MAAM,KAAKJ,KAAL,CAAWE,GAAX,CAAeE,IAAvB,EAA3B;AACD;;;uCAEkB;AAAA,uBAWb,KAAKJ,KAAL,CAAWE,GAXE;AAAA,UAEfG,IAFe,cAEfA,IAFe;AAAA,UAGfC,KAHe,cAGfA,KAHe;AAAA,UAIfF,IAJe,cAIfA,IAJe;AAAA,UAKfG,QALe,cAKfA,QALe;AAAA,UAMfC,KANe,cAMfA,KANe;AAAA,UAOfC,eAPe,cAOfA,eAPe;AAAA,UAQfN,WARe,cAQfA,WARe;AAAA,UASfO,YATe,cASfA,YATe;AAAA,UAUfC,iBAVe,cAUfA,iBAVe;;AAYjB,UAAIJ,aAAa,OAAjB,EAA0B;AACxB;AACA,eACE;AAAA;AAAA,YAAK,WAAU,wBAAf,EAAwC,SAASI,iBAAjD;AACE;AAAA;AAAA;AAAA;AAAA;AADF,SADF;AAKD,OAPD,MAOO,IAAIJ,aAAa,MAAjB,EAAyB;AAC9B,YAAI,CAACE,eAAD,IAAoBJ,KAAKO,MAAL,KAAgBN,KAAxC,EAA+C;AAC7C,iBACE;AAAA;AAAA;AACE,yBAAU,wBADZ;AAEE,uBAAS,mBAAM;AACbH,4BAAY,EAAEC,MAAMA,OAAO,CAAf,EAAZ;AACAM,6BAAaN,OAAO,CAApB;AACD;AALH;AAOE;AAAA;AAAA;AAAOS,2CAAKC,GAAL,CAAS,qBAAT;AAAP;AAPF,WADF;AAWD,SAZD,MAYO;AACL,iBAAO,IAAP;AACD;AACF,OAhBM,MAgBA,IAAIP,aAAa,YAAjB,EAA+B;AACpC,eACE;AAAA;AAAA,YAAK,WAAU,yBAAf;AACE;AACE,sBAAUC,KADZ;AAEE,qBAASJ,IAFX;AAGE,mBAAOE,KAHT;AAIE,sBAAU,qBAAK;AACbH,0BAAY,EAAEC,MAAMW,CAAR,EAAZ;AACAL,2BAAaK,CAAb;AACD;AAPH;AADF,SADF;AAaD;AACF;;;6BAEQ;AAAA,wBAC0B,KAAKf,KAAL,CAAWE,GADrC;AAAA,UACCG,IADD,eACCA,IADD;AAAA,UACOC,KADP,eACOA,KADP;AAAA,UACcU,OADd,eACcA,OADd;;;AAGP,UAAMC,WAAWC,QACfF,QAAQb,WAAR,IAAuBa,QAAQG,aAA/B,IAAgDH,QAAQI,WADzC,CAAjB;AAGA,aACE;AAAA;AAAA;AACE;AAAA;AAAA,YAAM,UAAUH,QAAhB;AAEE;AAAA;AAAA;AAAMJ,yCAAKC,GAAL,CAAS,sBAAT,EAAiC,EAAER,YAAF,EAAjC;AAAN,WAFF;AAGGD,eAAKgB,GAAL,CAAS;AAAA,mBACR,8BAAC,oBAAD,IAAY,SAASC,IAArB,EAA2B,KAAKA,KAAKC,EAArC,EAAyC,WAAWD,KAAKC,EAAzD,GADQ;AAAA,WAAT,CAHH;AAMG,eAAKC,gBAAL;AANH;AADF,OADF;AAYD;;;;EAhFuBC,gB;;AAmF1B1B,YAAY2B,SAAZ,GAAwB,EAAxB;;kBAEe,uBAAQ3B,WAAR,C","file":"index.js","sourcesContent":["import React, { Component } from \"react\";\nimport { Spin, Pagination } from \"antd\";\nimport intl from \"react-intl-universal\";\nimport Comment from \"../../Comment\";\nimport CommentBox from \"../CommentBox\";\nimport \"./index.css\";\n\nclass CommentList extends Component {\n  constructor(props) {\n    super(props);\n    this.state = {};\n  }\n\n  componentWillMount() {\n    this.props.app.sGetComment({ page: this.props.app.page });\n  }\n\n  renderPagination() {\n    const {\n      list,\n      total,\n      page,\n      pageType,\n      limit,\n      isNoMoreComment,\n      sGetComment,\n      onPageChange,\n      onGetMoreBtnClick\n    } = this.props.app;\n    if (pageType === \"slice\") {\n      // 截断多余评论,通过点击查看更多跳转\n      return (\n        <div className=\"comment-list-show-more\" onClick={onGetMoreBtnClick}>\n          <span>查看更多</span>\n        </div>\n      );\n    } else if (pageType === \"more\") {\n      if (!isNoMoreComment && list.length !== total) {\n        return (\n          <div\n            className=\"comment-list-show-more\"\n            onClick={() => {\n              sGetComment({ page: page + 1 });\n              onPageChange(page + 1);\n            }}\n          >\n            <span>{intl.get(\"comment.moreComment\")}</span>\n          </div>\n        );\n      } else {\n        return null;\n      }\n    } else if (pageType === \"pagination\") {\n      return (\n        <div className=\"comment-list-pagination\">\n          <Pagination\n            pageSize={limit}\n            current={page}\n            total={total}\n            onChange={p => {\n              sGetComment({ page: p });\n              onPageChange(p);\n            }}\n          />\n        </div>\n      );\n    }\n  }\n\n  render() {\n    const { list, total, loading } = this.props.app;\n\n    const spinning = Boolean(\n      loading.sGetComment || loading.sCommentFavor || loading.sReplyFavor\n    );\n    return (\n      <div>\n        <Spin spinning={spinning}>\n          {/* <div>共 {total} 条评论</div> */}\n          <div>{intl.get(\"comment.totalComment\", { total })}</div>\n          {list.map(item => (\n            <CommentBox content={item} key={item.id} commentId={item.id} />\n          ))}\n          {this.renderPagination()}\n        </Spin>\n      </div>\n    );\n  }\n}\n\nCommentList.propTypes = {};\n\nexport default Comment(CommentList);\n"]}
1
+{"version":3,"sources":["../../../src/components/CommentList/index.js"],"names":["CommentList","props","state","app","sGetComment","page","list","total","pageType","limit","isNoMoreComment","onPageChange","onGetMoreBtnClick","length","intl","get","p","loading","spinning","Boolean","sCommentFavor","sReplyFavor","map","item","user_id","id","renderPagination","Component","propTypes"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;;;;AAEA;;;;AACA;;;;AACA;;;;AACA;;;;;;;;;;IAEMA,W;;;AACJ,uBAAYC,KAAZ,EAAmB;AAAA;;AAAA,0HACXA,KADW;;AAEjB,UAAKC,KAAL,GAAa,EAAb;AAFiB;AAGlB;;;;yCAEoB;AACnB,WAAKD,KAAL,CAAWE,GAAX,CAAeC,WAAf,CAA2B,EAAEC,MAAM,KAAKJ,KAAL,CAAWE,GAAX,CAAeE,IAAvB,EAA3B;AACD;;;uCAEkB;AAAA,uBAWb,KAAKJ,KAAL,CAAWE,GAXE;AAAA,UAEfG,IAFe,cAEfA,IAFe;AAAA,UAGfC,KAHe,cAGfA,KAHe;AAAA,UAIfF,IAJe,cAIfA,IAJe;AAAA,UAKfG,QALe,cAKfA,QALe;AAAA,UAMfC,KANe,cAMfA,KANe;AAAA,UAOfC,eAPe,cAOfA,eAPe;AAAA,UAQfN,WARe,cAQfA,WARe;AAAA,UASfO,YATe,cASfA,YATe;AAAA,UAUfC,iBAVe,cAUfA,iBAVe;;AAYjB,UAAIJ,aAAa,OAAjB,EAA0B;AACxB;AACA,eACE;AAAA;AAAA,YAAK,WAAU,wBAAf,EAAwC,SAASI,iBAAjD;AACE;AAAA;AAAA;AAAA;AAAA;AADF,SADF;AAKD,OAPD,MAOO,IAAIJ,aAAa,MAAjB,EAAyB;AAC9B,YAAI,CAACE,eAAD,IAAoBJ,KAAKO,MAAL,KAAgBN,KAAxC,EAA+C;AAC7C,iBACE;AAAA;AAAA;AACE,yBAAU,wBADZ;AAEE,uBAAS,mBAAM;AACbH,4BAAY,EAAEC,MAAMA,OAAO,CAAf,EAAZ;AACAM,6BAAaN,OAAO,CAApB;AACD;AALH;AAOE;AAAA;AAAA;AAAOS,2CAAKC,GAAL,CAAS,qBAAT;AAAP;AAPF,WADF;AAWD,SAZD,MAYO;AACL,iBAAO,IAAP;AACD;AACF,OAhBM,MAgBA,IAAIP,aAAa,YAAjB,EAA+B;AACpC,eACE;AAAA;AAAA,YAAK,WAAU,yBAAf;AACE;AACE,sBAAUC,KADZ;AAEE,qBAASJ,IAFX;AAGE,mBAAOE,KAHT;AAIE,sBAAU,qBAAK;AACbH,0BAAY,EAAEC,MAAMW,CAAR,EAAZ;AACAL,2BAAaK,CAAb;AACD;AAPH;AADF,SADF;AAaD;AACF;;;6BAEQ;AAAA,wBAC0B,KAAKf,KAAL,CAAWE,GADrC;AAAA,UACCG,IADD,eACCA,IADD;AAAA,UACOC,KADP,eACOA,KADP;AAAA,UACcU,OADd,eACcA,OADd;;;AAGP,UAAMC,WAAWC,QACfF,QAAQb,WAAR,IAAuBa,QAAQG,aAA/B,IAAgDH,QAAQI,WADzC,CAAjB;AAGA,aACE;AAAA;AAAA;AACE;AAAA;AAAA,YAAM,UAAUH,QAAhB;AAEE;AAAA;AAAA;AAAMJ,yCAAKC,GAAL,CAAS,sBAAT,EAAiC,EAAER,YAAF,EAAjC;AAAN,WAFF;AAGGD,eAAKgB,GAAL,CAAS;AAAA,mBACR,8BAAC,oBAAD;AACE,uBAASC,IADX;AAEE,uBAASA,KAAKC,OAFhB;AAGE,mBAAKD,KAAKE,EAHZ;AAIE,yBAAWF,KAAKE;AAJlB,cADQ;AAAA,WAAT,CAHH;AAWG,eAAKC,gBAAL;AAXH;AADF,OADF;AAiBD;;;;EArFuBC,gB;;AAwF1B3B,YAAY4B,SAAZ,GAAwB,EAAxB;;kBAEe,uBAAQ5B,WAAR,C","file":"index.js","sourcesContent":["import React, { Component } from \"react\";\nimport { Spin, Pagination } from \"antd\";\nimport intl from \"react-intl-universal\";\nimport Comment from \"../../Comment\";\nimport CommentBox from \"../CommentBox\";\nimport \"./index.css\";\n\nclass CommentList extends Component {\n  constructor(props) {\n    super(props);\n    this.state = {};\n  }\n\n  componentWillMount() {\n    this.props.app.sGetComment({ page: this.props.app.page });\n  }\n\n  renderPagination() {\n    const {\n      list,\n      total,\n      page,\n      pageType,\n      limit,\n      isNoMoreComment,\n      sGetComment,\n      onPageChange,\n      onGetMoreBtnClick\n    } = this.props.app;\n    if (pageType === \"slice\") {\n      // 截断多余评论,通过点击查看更多跳转\n      return (\n        <div className=\"comment-list-show-more\" onClick={onGetMoreBtnClick}>\n          <span>查看更多</span>\n        </div>\n      );\n    } else if (pageType === \"more\") {\n      if (!isNoMoreComment && list.length !== total) {\n        return (\n          <div\n            className=\"comment-list-show-more\"\n            onClick={() => {\n              sGetComment({ page: page + 1 });\n              onPageChange(page + 1);\n            }}\n          >\n            <span>{intl.get(\"comment.moreComment\")}</span>\n          </div>\n        );\n      } else {\n        return null;\n      }\n    } else if (pageType === \"pagination\") {\n      return (\n        <div className=\"comment-list-pagination\">\n          <Pagination\n            pageSize={limit}\n            current={page}\n            total={total}\n            onChange={p => {\n              sGetComment({ page: p });\n              onPageChange(p);\n            }}\n          />\n        </div>\n      );\n    }\n  }\n\n  render() {\n    const { list, total, loading } = this.props.app;\n\n    const spinning = Boolean(\n      loading.sGetComment || loading.sCommentFavor || loading.sReplyFavor\n    );\n    return (\n      <div>\n        <Spin spinning={spinning}>\n          {/* <div>共 {total} 条评论</div> */}\n          <div>{intl.get(\"comment.totalComment\", { total })}</div>\n          {list.map(item => (\n            <CommentBox\n              content={item}\n              user_id={item.user_id}\n              key={item.id}\n              commentId={item.id}\n            />\n          ))}\n          {this.renderPagination()}\n        </Spin>\n      </div>\n    );\n  }\n}\n\nCommentList.propTypes = {};\n\nexport default Comment(CommentList);\n"]}

+ 178
- 0
lib/components/ContentItem/AvatarHoverCard.js View File

1
+"use strict";
2
+
3
+Object.defineProperty(exports, "__esModule", {
4
+  value: true
5
+});
6
+
7
+var _col = require("antd/es/col");
8
+
9
+var _col2 = _interopRequireDefault(_col);
10
+
11
+var _row = require("antd/es/row");
12
+
13
+var _row2 = _interopRequireDefault(_row);
14
+
15
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
16
+
17
+require("antd/es/col/style/css");
18
+
19
+require("antd/es/row/style/css");
20
+
21
+var _react = require("react");
22
+
23
+var _react2 = _interopRequireDefault(_react);
24
+
25
+var _reactIntlUniversal = require("react-intl-universal");
26
+
27
+var _reactIntlUniversal2 = _interopRequireDefault(_reactIntlUniversal);
28
+
29
+require("./AvatarHoverCard.less");
30
+
31
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
32
+
33
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
34
+
35
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
36
+
37
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
38
+
39
+var AvatarHoverCard = function (_Component) {
40
+  _inherits(AvatarHoverCard, _Component);
41
+
42
+  function AvatarHoverCard(props) {
43
+    _classCallCheck(this, AvatarHoverCard);
44
+
45
+    var _this = _possibleConstructorReturn(this, (AvatarHoverCard.__proto__ || Object.getPrototypeOf(AvatarHoverCard)).call(this, props));
46
+
47
+    _this.state = {
48
+      showModal: false
49
+    };
50
+    return _this;
51
+  }
52
+
53
+  _createClass(AvatarHoverCard, [{
54
+    key: "componentDidMount",
55
+    value: function componentDidMount() {
56
+      this.props.getUserInfo({
57
+        id: this.props.user_id
58
+      });
59
+    }
60
+  }, {
61
+    key: "render",
62
+    value: function render() {
63
+      var _this2 = this;
64
+
65
+      var _props = this.props,
66
+          image = _props.image,
67
+          user_id = _props.user_id,
68
+          currentUser = _props.currentUser,
69
+          userAvaHoverData = _props.userAvaHoverData;
70
+
71
+      var followed = userAvaHoverData[user_id] && userAvaHoverData[user_id].isFollowed;
72
+
73
+      return _react2.default.createElement(
74
+        "div",
75
+        { className: "AvatarHoverCard", onClick: function onClick(e) {
76
+            return e.stopPropagation();
77
+          } },
78
+        _react2.default.createElement(
79
+          "div",
80
+          { onClick: this.props.userAvaClick },
81
+          _react2.default.createElement(
82
+            _row2.default,
83
+            { type: "flex", className: "rowUser" },
84
+            _react2.default.createElement("div", {
85
+              className: "avatar",
86
+              style: {
87
+                backgroundImage: "url(" + image + ")"
88
+              }
89
+            }),
90
+            _react2.default.createElement(
91
+              "div",
92
+              { className: "nickname" },
93
+              userAvaHoverData[user_id] && userAvaHoverData[user_id].nickname
94
+            )
95
+          )
96
+        ),
97
+        _react2.default.createElement("div", { className: "divider" }),
98
+        _react2.default.createElement(
99
+          _row2.default,
100
+          { type: "flex", className: "rowNum" },
101
+          _react2.default.createElement(
102
+            _col2.default,
103
+            { className: "colFans" },
104
+            _react2.default.createElement(
105
+              "div",
106
+              { className: "count" },
107
+              userAvaHoverData[user_id] && userAvaHoverData[user_id].fans
108
+            ),
109
+            _react2.default.createElement(
110
+              "div",
111
+              { className: "text" },
112
+              _reactIntlUniversal2.default.get("bilingually.fan", {
113
+                ext: userAvaHoverData[user_id] && userAvaHoverData[user_id].fans > 1 ? "s" : ""
114
+              })
115
+            )
116
+          ),
117
+          _react2.default.createElement(_col2.default, { className: "hdivider" }),
118
+          _react2.default.createElement(
119
+            _col2.default,
120
+            { className: "colFollow" },
121
+            _react2.default.createElement(
122
+              "div",
123
+              { className: "count" },
124
+              userAvaHoverData[user_id] && userAvaHoverData[user_id].followers
125
+            ),
126
+            _react2.default.createElement(
127
+              "div",
128
+              { className: "text" },
129
+              _reactIntlUniversal2.default.get("bilingually.follow", {
130
+                ext: userAvaHoverData[user_id] && userAvaHoverData[user_id].followers > 1 ? "s" : ""
131
+              })
132
+            )
133
+          )
134
+        ),
135
+        currentUser.user_id !== user_id && _react2.default.createElement(
136
+          _row2.default,
137
+          { type: "flex", className: "rowBtn" },
138
+          followed ? _react2.default.createElement(
139
+            "div",
140
+            {
141
+              className: "unFollowBtn",
142
+              onClick: function onClick(e) {
143
+                e.stopPropagation();
144
+                _this2.props.unFocus({
145
+                  id: user_id
146
+                }).then(function () {
147
+                  _this2.props.getUserInfo({
148
+                    id: user_id
149
+                  });
150
+                });
151
+              }
152
+            },
153
+            _reactIntlUniversal2.default.get("bilingually.cancel_follow")
154
+          ) : _react2.default.createElement(
155
+            "div",
156
+            {
157
+              className: "followBtn",
158
+              onClick: function onClick(e) {
159
+                e.stopPropagation();
160
+                _this2.props.focus({ id: user_id }).then(function () {
161
+                  _this2.props.getUserInfo({
162
+                    id: user_id
163
+                  });
164
+                });
165
+              }
166
+            },
167
+            _reactIntlUniversal2.default.get("bilingually.follow", { ext: "" })
168
+          )
169
+        )
170
+      );
171
+    }
172
+  }]);
173
+
174
+  return AvatarHoverCard;
175
+}(_react.Component);
176
+
177
+exports.default = AvatarHoverCard;
178
+//# sourceMappingURL=AvatarHoverCard.js.map

+ 1
- 0
lib/components/ContentItem/AvatarHoverCard.js.map
File diff suppressed because it is too large
View File


+ 146
- 0
lib/components/ContentItem/AvatarHoverCard.less View File

1
+.AvatarHoverCard {
2
+  width: 260px;
3
+  padding: 14px 18px;
4
+}
5
+
6
+.rowUser {
7
+  align-items: center;
8
+}
9
+.avatar {
10
+  width: 48px;
11
+  height: 48px;
12
+  border-radius: 24px;
13
+  background-position: center;
14
+  background-size: cover;
15
+}
16
+.nickname {
17
+  font-size: 16px;
18
+  color: rgba(58, 58, 58, 1);
19
+  margin-left: 14px;
20
+}
21
+.divider {
22
+  height: 1px;
23
+  background: #e2e2e2;
24
+  margin: 12px 0;
25
+}
26
+.rowNum {
27
+  height: 45px;
28
+  align-items: center;
29
+}
30
+.colFans,
31
+.colFollow {
32
+  flex: 1;
33
+  text-align: center;
34
+  .count {
35
+    font-size: 17px;
36
+    font-weight: 500;
37
+    color: rgba(5, 18, 11, 1);
38
+  }
39
+  .text {
40
+    font-size: 14px;
41
+    font-weight: 400;
42
+    color: rgba(140, 140, 140, 1);
43
+  }
44
+}
45
+.hdivider {
46
+  width: 1px;
47
+  height: 25px;
48
+  background: #e2e2e2;
49
+}
50
+.rowBtn {
51
+  margin-top: 14px;
52
+  margin-bottom: 10px;
53
+  justify-content: space-around;
54
+}
55
+.followBtn,
56
+.unFollowBtn,
57
+.privateMessageBtn {
58
+  width: 77px;
59
+  height: 31px;
60
+  line-height: 31px;
61
+  background: rgba(113, 193, 53, 1);
62
+  border-radius: 4px;
63
+  color: #fff;
64
+  font-size: 12px;
65
+  font-weight: 500;
66
+  text-align: center;
67
+  cursor: pointer;
68
+  margin: 0 5px;
69
+}
70
+
71
+.followBtn {
72
+  border: 1px solid rgba(113, 193, 53, 1);
73
+  color: rgba(113, 193, 53, 1);
74
+  background: #fff;
75
+}
76
+.unFollowBtn {
77
+  color: #fff;
78
+  background: rgba(113, 193, 53, 1);
79
+  border: 1px solid rgba(113, 193, 53, 1);
80
+}
81
+
82
+.modalContainer {
83
+  background: #fff;
84
+  padding: 20px;
85
+}
86
+
87
+.modalTitle {
88
+  color: #3a3a3a;
89
+  margin-left: 8px;
90
+  margin-bottom: 12px;
91
+  font-weight: 500;
92
+}
93
+
94
+.modalClose {
95
+  position: absolute;
96
+  top: 15px;
97
+  right: 15px;
98
+  font-size: 12px;
99
+}
100
+
101
+.nextComment {
102
+  width: 510px;
103
+  padding: 0;
104
+}
105
+.expressionBtnWrap,
106
+.pictureBtnWrap {
107
+  float: left;
108
+  width: 70px;
109
+  margin-top: 5px;
110
+  cursor: pointer;
111
+  .icon {
112
+    float: left;
113
+    color: #ffa405;
114
+    font-size: 18px !important;
115
+    margin: 0 !important;
116
+  }
117
+  .text {
118
+    float: left;
119
+    font-size: 12px;
120
+    color: #393939;
121
+    margin-left: 6px;
122
+  }
123
+}
124
+
125
+.btnGroup {
126
+  display: flex;
127
+}
128
+
129
+.cancelBtn,
130
+.submitBtn {
131
+  width: 77px;
132
+  height: 31px;
133
+  line-height: 31px;
134
+  background: rgba(113, 193, 53, 1);
135
+  border-radius: 4px;
136
+  color: #fff;
137
+  font-size: 12px;
138
+  font-weight: 500;
139
+  text-align: center;
140
+  cursor: pointer;
141
+}
142
+.cancelBtn {
143
+  background: #e9e9e9;
144
+  color: #6d6d6d;
145
+  margin-right: 12px;
146
+}

+ 11
- 0
lib/components/ContentItem/index.css View File

22
   border-radius: 20px;
22
   border-radius: 20px;
23
   background-position: center;
23
   background-position: center;
24
   background-size: cover;
24
   background-size: cover;
25
+  cursor: pointer;
25
 }
26
 }
26
 .comment-item-content {
27
 .comment-item-content {
27
   margin: 10px 0;
28
   margin: 10px 0;
87
   margin-right: 10px;
88
   margin-right: 10px;
88
 }
89
 }
89
 
90
 
91
+.avatar-hover-card-overlay {
92
+  padding-top: 0;
93
+}
94
+.avatar-hover-card-overlay .ant-popover-inner-content {
95
+  padding: 0;
96
+}
97
+.avatar-hover-card-overlay .ant-popover-arrow {
98
+  display: none;
99
+}
100
+
90
 @media screen and (max-width: 616px) and (min-width: 449px) {
101
 @media screen and (max-width: 616px) and (min-width: 449px) {
91
   .comment-item-right {
102
   .comment-item-right {
92
     display: inline-block;
103
     display: inline-block;

+ 61
- 5
lib/components/ContentItem/index.js View File

16
 
16
 
17
 var _tooltip2 = _interopRequireDefault(_tooltip);
17
 var _tooltip2 = _interopRequireDefault(_tooltip);
18
 
18
 
19
+var _popover = require("antd/es/popover");
20
+
21
+var _popover2 = _interopRequireDefault(_popover);
22
+
23
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
24
+
19
 var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
25
 var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
20
 
26
 
21
 require("antd/es/popconfirm/style/css");
27
 require("antd/es/popconfirm/style/css");
24
 
30
 
25
 require("antd/es/tooltip/style/css");
31
 require("antd/es/tooltip/style/css");
26
 
32
 
33
+require("antd/es/popover/style/css");
34
+
27
 var _react = require("react");
35
 var _react = require("react");
28
 
36
 
29
 var _react2 = _interopRequireDefault(_react);
37
 var _react2 = _interopRequireDefault(_react);
46
 
54
 
47
 var _reactIntlUniversal2 = _interopRequireDefault(_reactIntlUniversal);
55
 var _reactIntlUniversal2 = _interopRequireDefault(_reactIntlUniversal);
48
 
56
 
57
+var _AvatarHoverCard = require("./AvatarHoverCard");
58
+
59
+var _AvatarHoverCard2 = _interopRequireDefault(_AvatarHoverCard);
60
+
49
 var _Comment = require("../../Comment");
61
 var _Comment = require("../../Comment");
50
 
62
 
51
 var _Comment2 = _interopRequireDefault(_Comment);
63
 var _Comment2 = _interopRequireDefault(_Comment);
98
     _this.state = {
110
     _this.state = {
99
       showInput: false,
111
       showInput: false,
100
       showPreviewer: false,
112
       showPreviewer: false,
101
-      previewerIndex: 0
113
+      previewerIndex: 0,
114
+      popoverVisible: false
102
     };
115
     };
103
     _this.handleToggleInput = _this.handleToggleInput.bind(_this);
116
     _this.handleToggleInput = _this.handleToggleInput.bind(_this);
104
     _this.renderTextWithReply = _this.renderTextWithReply.bind(_this);
117
     _this.renderTextWithReply = _this.renderTextWithReply.bind(_this);
105
     _this.showPreviewer = _this.showPreviewer.bind(_this);
118
     _this.showPreviewer = _this.showPreviewer.bind(_this);
106
     _this.hidePreviewer = _this.hidePreviewer.bind(_this);
119
     _this.hidePreviewer = _this.hidePreviewer.bind(_this);
120
+    _this.handleVisibleChange = _this.handleVisibleChange.bind(_this);
107
     return _this;
121
     return _this;
108
   }
122
   }
109
 
123
 
127
     value: function handleToggleInput() {
141
     value: function handleToggleInput() {
128
       this.setState({ showInput: !this.state.showInput });
142
       this.setState({ showInput: !this.state.showInput });
129
     }
143
     }
144
+  }, {
145
+    key: "handleVisibleChange",
146
+    value: function handleVisibleChange(visible) {
147
+      this.setState({
148
+        popoverVisible: visible
149
+      });
150
+    }
130
   }, {
151
   }, {
131
     key: "renderTextWithReply",
152
     key: "renderTextWithReply",
132
     value: function renderTextWithReply(text, content) {
153
     value: function renderTextWithReply(text, content) {
162
           action = _props.action,
183
           action = _props.action,
163
           showReply = _props.showReply,
184
           showReply = _props.showReply,
164
           onShowReply = _props.onShowReply,
185
           onShowReply = _props.onShowReply,
165
-          app = _props.app;
166
-      var locale = this.props.app.locale;
186
+          app = _props.app,
187
+          user_id = _props.user_id;
188
+      var _props$app = this.props.app,
189
+          locale = _props$app.locale,
190
+          userAvaClick = _props$app.userAvaClick,
191
+          showHoverCard = _props$app.showHoverCard;
167
       var showInput = this.state.showInput;
192
       var showInput = this.state.showInput;
168
 
193
 
169
 
194
 
196
         _react2.default.createElement(
221
         _react2.default.createElement(
197
           "div",
222
           "div",
198
           { className: "comment-item-left" },
223
           { className: "comment-item-left" },
199
-          _react2.default.createElement("div", {
224
+          showHoverCard ? _react2.default.createElement(
225
+            _popover2.default,
226
+            {
227
+              content: _react2.default.createElement(_AvatarHoverCard2.default, _extends({}, this.props.app, {
228
+                user_id: user_id,
229
+                handleVisibleChange: this.handleVisibleChange,
230
+                image: content.user_avatar || _avatar2.default
231
+              }))
232
+              // placement={this.props.placement}
233
+              // trigger="click"
234
+              , visible: this.state.popoverVisible,
235
+              onVisibleChange: this.handleVisibleChange,
236
+              overlayClassName: "avatar-hover-card-overlay"
237
+            },
238
+            _react2.default.createElement("div", {
239
+              className: "comment-item-avatar",
240
+              style: {
241
+                backgroundImage: "url(" + (content.user_avatar || _avatar2.default) + ")"
242
+              },
243
+              onClick: function onClick() {
244
+                return userAvaClick(user_id);
245
+              }
246
+            })
247
+          ) : _react2.default.createElement("div", {
200
             className: "comment-item-avatar",
248
             className: "comment-item-avatar",
201
             style: {
249
             style: {
202
               backgroundImage: "url(" + (content.user_avatar || _avatar2.default) + ")"
250
               backgroundImage: "url(" + (content.user_avatar || _avatar2.default) + ")"
251
+            },
252
+            onClick: function onClick() {
253
+              userAvaClick(user_id);
203
             }
254
             }
204
           })
255
           })
205
         ),
256
         ),
211
             null,
262
             null,
212
             _react2.default.createElement(
263
             _react2.default.createElement(
213
               "strong",
264
               "strong",
214
-              null,
265
+              {
266
+                onClick: function onClick() {
267
+                  return userAvaClick(user_id);
268
+                },
269
+                style: { cursor: "pointer" }
270
+              },
215
               content.user_name || _reactIntlUniversal2.default.get("comment.tourist")
271
               content.user_name || _reactIntlUniversal2.default.get("comment.tourist")
216
             ),
272
             ),
217
             _react2.default.createElement(
273
             _react2.default.createElement(

+ 1
- 1
lib/components/ContentItem/index.js.map
File diff suppressed because it is too large
View File


+ 43
- 0
lib/index.js View File

112
     businessId: "test",
112
     businessId: "test",
113
     businessUserId: 4,
113
     businessUserId: 4,
114
     userId: 71299,
114
     userId: 71299,
115
+    currentUser: {
116
+      user_id: 71748
117
+    },
118
+    userAvaHoverData: {
119
+      71763: {
120
+        nickname: "aaa",
121
+        followers: 20,
122
+        fans: 2,
123
+        isFollowed: true
124
+      },
125
+      71748: {
126
+        nickname: "L0",
127
+        followers: 10,
128
+        fans: 11,
129
+        isFollowed: false
130
+      },
131
+      71299: {
132
+        nickname: "narro",
133
+        followers: 10,
134
+        fans: 11,
135
+        isFollowed: false
136
+      }
137
+    },
138
+    showHoverCard: true,
139
+    userAvaClick: function userAvaClick(id) {
140
+      console.log("userAvaClick", id);
141
+    },
142
+    getUserInfo: function getUserInfo(id) {
143
+      console.log("getinfo:", id);
144
+    },
145
+    focus: function focus(id) {
146
+      return new Promise(function (resolve, reject) {
147
+        console.log("focus:", id);
148
+        resolve();
149
+      });
150
+    },
151
+    unFocus: function unFocus(id) {
152
+      return new Promise(function (resolve, reject) {
153
+        console.log("unFocus:", id);
154
+        resolve();
155
+      });
156
+    },
157
+
115
     onCountChange: function onCountChange(c) {
158
     onCountChange: function onCountChange(c) {
116
       console.log(c);
159
       console.log(c);
117
     },
160
     },

+ 1
- 1
lib/index.js.map
File diff suppressed because it is too large
View File


+ 3
- 3
lib/version.json View File

1
 {
1
 {
2
     "name":       "comment",
2
     "name":       "comment",
3
-    "buildDate":  1561545661645,
3
+    "buildDate":  1562073871881,
4
     "version":    "1.0.4",
4
     "version":    "1.0.4",
5
-    "numCommits": 156,
6
-    "hash":       "b06e101",
5
+    "numCommits": 158,
6
+    "hash":       "1b15efb",
7
     "dirty":      true
7
     "dirty":      true
8
 }
8
 }

+ 1
- 0
package.json View File

46
     "babel-plugin-import": "^1.8.0",
46
     "babel-plugin-import": "^1.8.0",
47
     "babel-plugin-transform-object-rest-spread": "^6.26.0",
47
     "babel-plugin-transform-object-rest-spread": "^6.26.0",
48
     "babel-preset-env": "^1.7.0",
48
     "babel-preset-env": "^1.7.0",
49
+    "babel-preset-es2015": "^6.24.1",
49
     "babel-preset-react": "^6.24.1",
50
     "babel-preset-react": "^6.24.1",
50
     "husky": "^0.14.3",
51
     "husky": "^0.14.3",
51
     "lint-staged": "^7.2.0",
52
     "lint-staged": "^7.2.0",

+ 3
- 1
src/components/CommentBox/index.js View File

58
                   replyId={item.id}
58
                   replyId={item.id}
59
                   key={item.id}
59
                   key={item.id}
60
                   content={item}
60
                   content={item}
61
+                  user_id={item.user_id}
61
                   action="replyToReply" // 回复的回复
62
                   action="replyToReply" // 回复的回复
62
                 />,
63
                 />,
63
                 <div className="comment-more-box" key="show_more_button">
64
                 <div className="comment-more-box" key="show_more_button">
96
   }
97
   }
97
 
98
 
98
   render() {
99
   render() {
99
-    const { content } = this.props;
100
+    const { content, user_id } = this.props;
100
     const { showReply } = this.state;
101
     const { showReply } = this.state;
101
     return (
102
     return (
102
       <div>
103
       <div>
105
           onShowReply={this.handleToggleReply}
106
           onShowReply={this.handleToggleReply}
106
           showReply={showReply}
107
           showReply={showReply}
107
           commentId={content.id}
108
           commentId={content.id}
109
+          user_id={user_id}
108
           action="reply" // 评论的回复
110
           action="reply" // 评论的回复
109
         />
111
         />
110
         {this.renderReplies(
112
         {this.renderReplies(

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

79
           {/* <div>共 {total} 条评论</div> */}
79
           {/* <div>共 {total} 条评论</div> */}
80
           <div>{intl.get("comment.totalComment", { total })}</div>
80
           <div>{intl.get("comment.totalComment", { total })}</div>
81
           {list.map(item => (
81
           {list.map(item => (
82
-            <CommentBox content={item} key={item.id} commentId={item.id} />
82
+            <CommentBox
83
+              content={item}
84
+              user_id={item.user_id}
85
+              key={item.id}
86
+              commentId={item.id}
87
+            />
83
           ))}
88
           ))}
84
           {this.renderPagination()}
89
           {this.renderPagination()}
85
         </Spin>
90
         </Spin>

+ 124
- 0
src/components/ContentItem/AvatarHoverCard.js View File

1
+import React, { Component } from "react";
2
+import { Row, Col } from "antd";
3
+import intl from "react-intl-universal";
4
+import "./AvatarHoverCard.less";
5
+
6
+class AvatarHoverCard extends Component {
7
+  constructor(props) {
8
+    super(props);
9
+    this.state = {
10
+      showModal: false
11
+    };
12
+  }
13
+
14
+  componentDidMount() {
15
+    this.props.getUserInfo({
16
+      id: this.props.user_id
17
+    });
18
+  }
19
+
20
+  render() {
21
+    const { image, user_id, currentUser, userAvaHoverData } = this.props;
22
+    const followed =
23
+      userAvaHoverData[user_id] && userAvaHoverData[user_id].isFollowed;
24
+
25
+    return (
26
+      <div className="AvatarHoverCard" onClick={e => e.stopPropagation()}>
27
+        {/* <Link to={`/bilingual/user/${user_id}`}> */}
28
+        <div onClick={this.props.userAvaClick}>
29
+          <Row type="flex" className="rowUser">
30
+            <div
31
+              className="avatar"
32
+              style={{
33
+                backgroundImage: `url(${image})`
34
+              }}
35
+            />
36
+            <div className="nickname">
37
+              {userAvaHoverData[user_id] && userAvaHoverData[user_id].nickname}
38
+            </div>
39
+          </Row>
40
+        </div>
41
+        {/* </Link> */}
42
+        <div className="divider" />
43
+        <Row type="flex" className="rowNum">
44
+          <Col className="colFans">
45
+            <div className="count">
46
+              {userAvaHoverData[user_id] && userAvaHoverData[user_id].fans}
47
+            </div>
48
+            <div className="text">
49
+              {intl.get("bilingually.fan", {
50
+                ext:
51
+                  userAvaHoverData[user_id] &&
52
+                  userAvaHoverData[user_id].fans > 1
53
+                    ? "s"
54
+                    : ""
55
+              })}
56
+            </div>
57
+          </Col>
58
+          <Col className="hdivider" />
59
+          <Col className="colFollow">
60
+            <div className="count">
61
+              {userAvaHoverData[user_id] && userAvaHoverData[user_id].followers}
62
+            </div>
63
+            <div className="text">
64
+              {intl.get("bilingually.follow", {
65
+                ext:
66
+                  userAvaHoverData[user_id] &&
67
+                  userAvaHoverData[user_id].followers > 1
68
+                    ? "s"
69
+                    : ""
70
+              })}
71
+            </div>
72
+          </Col>
73
+        </Row>
74
+        {currentUser.user_id !== user_id && (
75
+          <Row type="flex" className="rowBtn">
76
+            {followed ? (
77
+              <div
78
+                className="unFollowBtn"
79
+                onClick={e => {
80
+                  e.stopPropagation();
81
+                  this.props
82
+                    .unFocus({
83
+                      id: user_id
84
+                    })
85
+                    .then(() => {
86
+                      this.props.getUserInfo({
87
+                        id: user_id
88
+                      });
89
+                    });
90
+                }}
91
+              >
92
+                {intl.get("bilingually.cancel_follow")}
93
+              </div>
94
+            ) : (
95
+              <div
96
+                className="followBtn"
97
+                onClick={e => {
98
+                  e.stopPropagation();
99
+                  this.props.focus({ id: user_id }).then(() => {
100
+                    this.props.getUserInfo({
101
+                      id: user_id
102
+                    });
103
+                  });
104
+                }}
105
+              >
106
+                {intl.get("bilingually.follow", { ext: "" })}
107
+              </div>
108
+            )}
109
+
110
+            {/* 发私信按钮,暂时隐藏 */}
111
+            {/* <div
112
+            className={styles.privateMessageBtn}
113
+            onClick={this.toggleShowModal}
114
+          >
115
+            发私信
116
+          </div> */}
117
+          </Row>
118
+        )}
119
+      </div>
120
+    );
121
+  }
122
+}
123
+
124
+export default AvatarHoverCard;

+ 146
- 0
src/components/ContentItem/AvatarHoverCard.less View File

1
+.AvatarHoverCard {
2
+  width: 260px;
3
+  padding: 14px 18px;
4
+}
5
+
6
+.rowUser {
7
+  align-items: center;
8
+}
9
+.avatar {
10
+  width: 48px;
11
+  height: 48px;
12
+  border-radius: 24px;
13
+  background-position: center;
14
+  background-size: cover;
15
+}
16
+.nickname {
17
+  font-size: 16px;
18
+  color: rgba(58, 58, 58, 1);
19
+  margin-left: 14px;
20
+}
21
+.divider {
22
+  height: 1px;
23
+  background: #e2e2e2;
24
+  margin: 12px 0;
25
+}
26
+.rowNum {
27
+  height: 45px;
28
+  align-items: center;
29
+}
30
+.colFans,
31
+.colFollow {
32
+  flex: 1;
33
+  text-align: center;
34
+  .count {
35
+    font-size: 17px;
36
+    font-weight: 500;
37
+    color: rgba(5, 18, 11, 1);
38
+  }
39
+  .text {
40
+    font-size: 14px;
41
+    font-weight: 400;
42
+    color: rgba(140, 140, 140, 1);
43
+  }
44
+}
45
+.hdivider {
46
+  width: 1px;
47
+  height: 25px;
48
+  background: #e2e2e2;
49
+}
50
+.rowBtn {
51
+  margin-top: 14px;
52
+  margin-bottom: 10px;
53
+  justify-content: space-around;
54
+}
55
+.followBtn,
56
+.unFollowBtn,
57
+.privateMessageBtn {
58
+  width: 77px;
59
+  height: 31px;
60
+  line-height: 31px;
61
+  background: rgba(113, 193, 53, 1);
62
+  border-radius: 4px;
63
+  color: #fff;
64
+  font-size: 12px;
65
+  font-weight: 500;
66
+  text-align: center;
67
+  cursor: pointer;
68
+  margin: 0 5px;
69
+}
70
+
71
+.followBtn {
72
+  border: 1px solid rgba(113, 193, 53, 1);
73
+  color: rgba(113, 193, 53, 1);
74
+  background: #fff;
75
+}
76
+.unFollowBtn {
77
+  color: #fff;
78
+  background: rgba(113, 193, 53, 1);
79
+  border: 1px solid rgba(113, 193, 53, 1);
80
+}
81
+
82
+.modalContainer {
83
+  background: #fff;
84
+  padding: 20px;
85
+}
86
+
87
+.modalTitle {
88
+  color: #3a3a3a;
89
+  margin-left: 8px;
90
+  margin-bottom: 12px;
91
+  font-weight: 500;
92
+}
93
+
94
+.modalClose {
95
+  position: absolute;
96
+  top: 15px;
97
+  right: 15px;
98
+  font-size: 12px;
99
+}
100
+
101
+.nextComment {
102
+  width: 510px;
103
+  padding: 0;
104
+}
105
+.expressionBtnWrap,
106
+.pictureBtnWrap {
107
+  float: left;
108
+  width: 70px;
109
+  margin-top: 5px;
110
+  cursor: pointer;
111
+  .icon {
112
+    float: left;
113
+    color: #ffa405;
114
+    font-size: 18px !important;
115
+    margin: 0 !important;
116
+  }
117
+  .text {
118
+    float: left;
119
+    font-size: 12px;
120
+    color: #393939;
121
+    margin-left: 6px;
122
+  }
123
+}
124
+
125
+.btnGroup {
126
+  display: flex;
127
+}
128
+
129
+.cancelBtn,
130
+.submitBtn {
131
+  width: 77px;
132
+  height: 31px;
133
+  line-height: 31px;
134
+  background: rgba(113, 193, 53, 1);
135
+  border-radius: 4px;
136
+  color: #fff;
137
+  font-size: 12px;
138
+  font-weight: 500;
139
+  text-align: center;
140
+  cursor: pointer;
141
+}
142
+.cancelBtn {
143
+  background: #e9e9e9;
144
+  color: #6d6d6d;
145
+  margin-right: 12px;
146
+}

+ 11
- 0
src/components/ContentItem/index.css View File

22
   border-radius: 20px;
22
   border-radius: 20px;
23
   background-position: center;
23
   background-position: center;
24
   background-size: cover;
24
   background-size: cover;
25
+  cursor: pointer;
25
 }
26
 }
26
 .comment-item-content {
27
 .comment-item-content {
27
   margin: 10px 0;
28
   margin: 10px 0;
87
   margin-right: 10px;
88
   margin-right: 10px;
88
 }
89
 }
89
 
90
 
91
+.avatar-hover-card-overlay {
92
+  padding-top: 0;
93
+}
94
+.avatar-hover-card-overlay .ant-popover-inner-content {
95
+  padding: 0;
96
+}
97
+.avatar-hover-card-overlay .ant-popover-arrow {
98
+  display: none;
99
+}
100
+
90
 @media screen and (max-width: 616px) and (min-width: 449px) {
101
 @media screen and (max-width: 616px) and (min-width: 449px) {
91
   .comment-item-right {
102
   .comment-item-right {
92
     display: inline-block;
103
     display: inline-block;

+ 55
- 12
src/components/ContentItem/index.js View File

1
 import React, { Component } from "react";
1
 import React, { Component } from "react";
2
 import PropTypes from "prop-types";
2
 import PropTypes from "prop-types";
3
-import { Avatar, Icon, Tooltip, Popconfirm } from "antd";
3
+import { Icon, Tooltip, Popconfirm, Popover } from "antd";
4
 import dayjs from "dayjs";
4
 import dayjs from "dayjs";
5
 import "dayjs/locale/zh-cn";
5
 import "dayjs/locale/zh-cn";
6
 // import 'dayjs/locale/es';
6
 // import 'dayjs/locale/es';
7
 import relativeTime from "dayjs/plugin/relativeTime";
7
 import relativeTime from "dayjs/plugin/relativeTime";
8
 import intl from "react-intl-universal";
8
 import intl from "react-intl-universal";
9
+import AvatarHoverCard from "./AvatarHoverCard";
9
 import Comment from "../../Comment";
10
 import Comment from "../../Comment";
10
 import CommentInput from "../CommentInput";
11
 import CommentInput from "../CommentInput";
11
 import avatar from "../../avatar";
12
 import avatar from "../../avatar";
27
     this.state = {
28
     this.state = {
28
       showInput: false,
29
       showInput: false,
29
       showPreviewer: false,
30
       showPreviewer: false,
30
-      previewerIndex: 0
31
+      previewerIndex: 0,
32
+      popoverVisible: false
31
     };
33
     };
32
     this.handleToggleInput = this.handleToggleInput.bind(this);
34
     this.handleToggleInput = this.handleToggleInput.bind(this);
33
     this.renderTextWithReply = this.renderTextWithReply.bind(this);
35
     this.renderTextWithReply = this.renderTextWithReply.bind(this);
34
     this.showPreviewer = this.showPreviewer.bind(this);
36
     this.showPreviewer = this.showPreviewer.bind(this);
35
     this.hidePreviewer = this.hidePreviewer.bind(this);
37
     this.hidePreviewer = this.hidePreviewer.bind(this);
38
+    this.handleVisibleChange = this.handleVisibleChange.bind(this);
36
   }
39
   }
37
 
40
 
38
   showPreviewer(index) {
41
   showPreviewer(index) {
52
     this.setState({ showInput: !this.state.showInput });
55
     this.setState({ showInput: !this.state.showInput });
53
   }
56
   }
54
 
57
 
58
+  handleVisibleChange(visible) {
59
+    this.setState({
60
+      popoverVisible: visible
61
+    });
62
+  }
63
+
55
   renderTextWithReply(text, content) {
64
   renderTextWithReply(text, content) {
56
     let newText = text;
65
     let newText = text;
57
     const { reply } = content;
66
     const { reply } = content;
81
       action,
90
       action,
82
       showReply,
91
       showReply,
83
       onShowReply,
92
       onShowReply,
84
-      app
93
+      app,
94
+      user_id
85
     } = this.props;
95
     } = this.props;
86
 
96
 
87
-    const { locale } = this.props.app;
97
+    const { locale, userAvaClick, showHoverCard } = this.props.app;
88
     const { showInput } = this.state;
98
     const { showInput } = this.state;
89
 
99
 
90
     let newContent = content.content;
100
     let newContent = content.content;
116
     return (
126
     return (
117
       <div className="comment-item-box">
127
       <div className="comment-item-box">
118
         <div className="comment-item-left">
128
         <div className="comment-item-left">
119
-          {/* <Avatar src={content.user_avatar || avatar} size="large" /> */}
120
-          <div
121
-            className="comment-item-avatar"
122
-            style={{
123
-              backgroundImage: `url(${content.user_avatar || avatar})`
124
-            }}
125
-          />
129
+          {showHoverCard ? (
130
+            <Popover
131
+              content={
132
+                <AvatarHoverCard
133
+                  {...this.props.app}
134
+                  user_id={user_id}
135
+                  handleVisibleChange={this.handleVisibleChange}
136
+                  image={content.user_avatar || avatar}
137
+                />
138
+              }
139
+              // placement={this.props.placement}
140
+              // trigger="click"
141
+              visible={this.state.popoverVisible}
142
+              onVisibleChange={this.handleVisibleChange}
143
+              overlayClassName="avatar-hover-card-overlay"
144
+            >
145
+              <div
146
+                className="comment-item-avatar"
147
+                style={{
148
+                  backgroundImage: `url(${content.user_avatar || avatar})`
149
+                }}
150
+                onClick={() => userAvaClick(user_id)}
151
+              />
152
+            </Popover>
153
+          ) : (
154
+            <div
155
+              className="comment-item-avatar"
156
+              style={{
157
+                backgroundImage: `url(${content.user_avatar || avatar})`
158
+              }}
159
+              onClick={() => {
160
+                userAvaClick(user_id);
161
+              }}
162
+            />
163
+          )}
126
         </div>
164
         </div>
127
         <div className="comment-item-right">
165
         <div className="comment-item-right">
128
           <div>
166
           <div>
129
             {/* <a href={`/${content.user_id}`}>
167
             {/* <a href={`/${content.user_id}`}>
130
               {content.user_name || "暂无昵称"}
168
               {content.user_name || "暂无昵称"}
131
             </a> */}
169
             </a> */}
132
-            <strong>{content.user_name || intl.get("comment.tourist")}</strong>
170
+            <strong
171
+              onClick={() => userAvaClick(user_id)}
172
+              style={{ cursor: "pointer" }}
173
+            >
174
+              {content.user_name || intl.get("comment.tourist")}
175
+            </strong>
133
             <span style={{ marginLeft: 10 }}>
176
             <span style={{ marginLeft: 10 }}>
134
               <Tooltip
177
               <Tooltip
135
                 placement="top"
178
                 placement="top"

+ 43
- 0
src/index.js View File

77
     businessId: "test",
77
     businessId: "test",
78
     businessUserId: 4,
78
     businessUserId: 4,
79
     userId: 71299,
79
     userId: 71299,
80
+    currentUser: {
81
+      user_id: 71748
82
+    },
83
+    userAvaHoverData: {
84
+      71763: {
85
+        nickname: "aaa",
86
+        followers: 20,
87
+        fans: 2,
88
+        isFollowed: true
89
+      },
90
+      71748: {
91
+        nickname: "L0",
92
+        followers: 10,
93
+        fans: 11,
94
+        isFollowed: false
95
+      },
96
+      71299: {
97
+        nickname: "narro",
98
+        followers: 10,
99
+        fans: 11,
100
+        isFollowed: false
101
+      }
102
+    },
103
+    showHoverCard: true,
104
+    userAvaClick: id => {
105
+      console.log("userAvaClick", id);
106
+    },
107
+    getUserInfo: id => {
108
+      console.log("getinfo:", id);
109
+    },
110
+    focus: id => {
111
+      return new Promise(function(resolve, reject) {
112
+        console.log("focus:", id);
113
+        resolve();
114
+      });
115
+    },
116
+    unFocus: id => {
117
+      return new Promise(function(resolve, reject) {
118
+        console.log("unFocus:", id);
119
+        resolve();
120
+      });
121
+    },
122
+
80
     onCountChange: c => {
123
     onCountChange: c => {
81
       console.log(c);
124
       console.log(c);
82
     },
125
     },