@twreporter/react-components 8.5.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/CHANGELOG.md +544 -0
  2. package/LICENSE +21 -0
  3. package/README.md +46 -0
  4. package/lib/bookmark-list/bookmark.js +251 -0
  5. package/lib/bookmark-list/bookmarks.js +93 -0
  6. package/lib/bookmark-list/customized-link.js +45 -0
  7. package/lib/bookmark-list/image-wrapper.js +119 -0
  8. package/lib/bookmark-list/index.js +312 -0
  9. package/lib/bookmark-list/redirect-to-sign-in.js +35 -0
  10. package/lib/bookmark-widget/index.js +259 -0
  11. package/lib/confirmation/index.js +125 -0
  12. package/lib/donation-link.js +75 -0
  13. package/lib/error/index.js +17 -0
  14. package/lib/error/message.js +567 -0
  15. package/lib/footer/constants/paths.js +8 -0
  16. package/lib/footer/constants/styles.js +81 -0
  17. package/lib/footer/content.js +227 -0
  18. package/lib/footer/icon-list.js +191 -0
  19. package/lib/footer/index.js +123 -0
  20. package/lib/footer/logo.js +92 -0
  21. package/lib/is-fetching-wrapper.js +126 -0
  22. package/lib/link-with-tracker.js +153 -0
  23. package/lib/listing-page/components/image.js +185 -0
  24. package/lib/listing-page/components/list-item.js +197 -0
  25. package/lib/listing-page/components/list.js +188 -0
  26. package/lib/listing-page/components/topics/index.js +215 -0
  27. package/lib/listing-page/components/topics/page-content.js +44 -0
  28. package/lib/listing-page/components/topics/post-item.js +139 -0
  29. package/lib/listing-page/components/topics/posts.js +24 -0
  30. package/lib/listing-page/components/topics/section.js +104 -0
  31. package/lib/listing-page/components/topics/topic-item.js +206 -0
  32. package/lib/listing-page/constants/mockup-spec.js +39 -0
  33. package/lib/listing-page/constants/predefined-css.js +21 -0
  34. package/lib/listing-page/constants/topics.js +13 -0
  35. package/lib/listing-page/index.js +30 -0
  36. package/lib/mobile-pop-up-modal.js +161 -0
  37. package/lib/more.js +98 -0
  38. package/lib/pagination/index.js +310 -0
  39. package/lib/podcast-link.js +73 -0
  40. package/lib/side-bar/index.js +317 -0
  41. package/lib/table-of-contents/index.js +532 -0
  42. package/lib/utils/link-with-params.js +27 -0
  43. package/package.json +33 -0
@@ -0,0 +1,312 @@
1
+ "use strict";
2
+
3
+ function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports["default"] = void 0;
9
+
10
+ var _reactRedux = require("react-redux");
11
+
12
+ var _signInHref = require("@twreporter/core/lib/utils/sign-in-href");
13
+
14
+ var _bookmarks = _interopRequireDefault(require("./bookmarks"));
15
+
16
+ var _confirmation = _interopRequireDefault(require("../confirmation"));
17
+
18
+ var _propTypes = _interopRequireDefault(require("@twreporter/core/lib/constants/prop-types"));
19
+
20
+ var _CSSTransition = _interopRequireDefault(require("react-transition-group/CSSTransition"));
21
+
22
+ var _more = _interopRequireDefault(require("../more"));
23
+
24
+ var _propTypes2 = _interopRequireDefault(require("prop-types"));
25
+
26
+ var _react = _interopRequireDefault(require("react"));
27
+
28
+ var _redirectToSignIn = _interopRequireDefault(require("./redirect-to-sign-in"));
29
+
30
+ var _styledComponents = _interopRequireWildcard(require("styled-components"));
31
+
32
+ var _redux = _interopRequireDefault(require("@twreporter/redux"));
33
+
34
+ var _findIndex = _interopRequireDefault(require("lodash/findIndex"));
35
+
36
+ var _get = _interopRequireDefault(require("lodash/get"));
37
+
38
+ var _map = _interopRequireDefault(require("lodash/map"));
39
+
40
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
41
+
42
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
43
+
44
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
45
+
46
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
47
+
48
+ 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); } }
49
+
50
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
51
+
52
+ function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
53
+
54
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
55
+
56
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
57
+
58
+ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
59
+
60
+ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
61
+
62
+ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
63
+
64
+ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
65
+
66
+ var _twreporterRedux$acti = _redux["default"].actions,
67
+ deleteSingleBookmark = _twreporterRedux$acti.deleteSingleBookmark,
68
+ getMultipleBookmarks = _twreporterRedux$acti.getMultipleBookmarks;
69
+ var reduxStatePropKeys = _redux["default"].reduxStateFields;
70
+ var _ = {
71
+ findIndex: _findIndex["default"],
72
+ get: _get["default"],
73
+ map: _map["default"]
74
+ };
75
+ var defaultLimit = 5;
76
+ var defaultSort = 'created_at';
77
+ var text = {
78
+ dialog: {
79
+ content: '您確定要刪除這篇文章書籤?',
80
+ confirm: '確定',
81
+ cancel: '取消'
82
+ },
83
+ loadMore: '載入更多'
84
+ };
85
+ var transitionName = {
86
+ enter: 'effect-enter',
87
+ enterActive: 'effect-enter-active',
88
+ leave: 'effect-exit',
89
+ leaveActive: 'effect-exit-active'
90
+ };
91
+ var transitionDuration = {
92
+ enter: 400,
93
+ leave: 300
94
+ };
95
+
96
+ var MoreContainer = /*#__PURE__*/_styledComponents["default"].div.withConfig({
97
+ displayName: "bookmark-list__MoreContainer",
98
+ componentId: "w84xlj-0"
99
+ })(["display:", ";"], function (props) {
100
+ return props.hasMore ? 'inline' : 'none';
101
+ });
102
+
103
+ var reactTransitionCSS = /*#__PURE__*/(0, _styledComponents.css)([".", "{opacity:0.01;}.", "{opacity:1;transition:opacity ", "ms ease;}.", "{opacity:1;}.", "{opacity:0.01;transition:opacity ", "ms ease;}"], transitionName.enter, transitionName.enterActive, transitionDuration.enter, transitionName.leave, transitionName.leaveActive, transitionDuration.leave);
104
+
105
+ var Container = /*#__PURE__*/_styledComponents["default"].div.withConfig({
106
+ displayName: "bookmark-list__Container",
107
+ componentId: "w84xlj-1"
108
+ })(["", ""], reactTransitionCSS);
109
+
110
+ var BookmarkList = /*#__PURE__*/function (_React$Component) {
111
+ _inherits(BookmarkList, _React$Component);
112
+
113
+ var _super = _createSuper(BookmarkList);
114
+
115
+ function BookmarkList(props) {
116
+ var _this;
117
+
118
+ _classCallCheck(this, BookmarkList);
119
+
120
+ _this = _super.call(this, props);
121
+ _this.state = {
122
+ showConfirmation: false,
123
+ idToBeDeleted: null
124
+ };
125
+ _this.loadMoreBookmarks = _this.loadMoreBookmarks.bind(_assertThisInitialized(_this));
126
+ _this.handleDeleteButtonClicked = _this.handleDeleteButtonClicked.bind(_assertThisInitialized(_this));
127
+ _this.hideComfirmation = _this.hideComfirmation.bind(_assertThisInitialized(_this));
128
+ _this.handleDeletingConfirmed = _this.handleDeletingConfirmed.bind(_assertThisInitialized(_this));
129
+ _this._defaultBodyOverflow = 'scroll';
130
+ return _this;
131
+ }
132
+
133
+ _createClass(BookmarkList, [{
134
+ key: "componentDidMount",
135
+ value: function componentDidMount() {
136
+ this.checkAuthorization();
137
+ this._defaultBodyOverflow = _.get(document, 'body.style.overflow', this._defaultBodyOverflow);
138
+ var bookmarks = this.props.bookmarks;
139
+
140
+ if (!bookmarks.length) {
141
+ var _this$props = this.props,
142
+ jwt = _this$props.jwt,
143
+ userID = _this$props.userID,
144
+ _getMultipleBookmarks = _this$props.getMultipleBookmarks;
145
+ var offset = 0;
146
+
147
+ _getMultipleBookmarks(jwt, userID, offset, defaultLimit, defaultSort);
148
+ }
149
+ } // Redirect to singin page if user has not been authorized
150
+
151
+ }, {
152
+ key: "checkAuthorization",
153
+ value: function checkAuthorization() {
154
+ var _this$props2 = this.props,
155
+ isAuthed = _this$props2.isAuthed,
156
+ jwt = _this$props2.jwt;
157
+
158
+ if (!isAuthed || !jwt) {
159
+ var currentHref = typeof window === 'undefined' ? '' : window.location.href;
160
+ window.location.href = (0, _signInHref.getSignInHref)(currentHref);
161
+ }
162
+ }
163
+ }, {
164
+ key: "loadMoreBookmarks",
165
+ value: function loadMoreBookmarks() {
166
+ var _this$props3 = this.props,
167
+ total = _this$props3.total,
168
+ bookmarks = _this$props3.bookmarks,
169
+ jwt = _this$props3.jwt,
170
+ userID = _this$props3.userID,
171
+ getMultipleBookmarks = _this$props3.getMultipleBookmarks;
172
+ var offset = bookmarks.length;
173
+
174
+ if (offset < total) {
175
+ getMultipleBookmarks(jwt, userID, offset, defaultLimit, defaultSort);
176
+ }
177
+ }
178
+ }, {
179
+ key: "handleDeleteButtonClicked",
180
+ value: function handleDeleteButtonClicked(bookmarkID) {
181
+ this.setRecordToBeDeleted(bookmarkID);
182
+ this.showConfirmation();
183
+ }
184
+ }, {
185
+ key: "setRecordToBeDeleted",
186
+ value: function setRecordToBeDeleted(bookmarkID) {
187
+ this.setState({
188
+ idToBeDeleted: bookmarkID
189
+ });
190
+ }
191
+ }, {
192
+ key: "handleDeletingConfirmed",
193
+ value: function handleDeletingConfirmed() {
194
+ this.hideComfirmation();
195
+ var idToBeDeleted = this.state.idToBeDeleted;
196
+
197
+ if (typeof idToBeDeleted === 'number') {
198
+ var _this$props4 = this.props,
199
+ jwt = _this$props4.jwt,
200
+ userID = _this$props4.userID,
201
+ _deleteSingleBookmark = _this$props4.deleteSingleBookmark;
202
+
203
+ _deleteSingleBookmark(jwt, userID, idToBeDeleted);
204
+ } else {
205
+ console.error("Deleting bookmark failed. Bookmark id should be a number, but is ".concat(idToBeDeleted)); // eslint-disable-line no-console
206
+ }
207
+
208
+ this.setRecordToBeDeleted(null);
209
+ }
210
+ }, {
211
+ key: "hideComfirmation",
212
+ value: function hideComfirmation() {
213
+ var _this2 = this;
214
+
215
+ this.setState({
216
+ showConfirmation: false
217
+ }, function () {
218
+ document.body.style.overflow = _this2._defaultBodyOverflow;
219
+ });
220
+ }
221
+ }, {
222
+ key: "showConfirmation",
223
+ value: function showConfirmation() {
224
+ this.setState({
225
+ showConfirmation: true
226
+ }, function () {
227
+ document.body.style.overflow = 'hidden';
228
+ });
229
+ }
230
+ }, {
231
+ key: "render",
232
+ value: function render() {
233
+ var _this$props5 = this.props,
234
+ isAuthed = _this$props5.isAuthed,
235
+ jwt = _this$props5.jwt;
236
+ if (!isAuthed || !jwt) return /*#__PURE__*/_react["default"].createElement(_redirectToSignIn["default"], null, "\u60A8\u5C1A\u672A\u767B\u5165\uFF0C\u5C07\u8DF3\u8F49\u81F3\u767B\u5165\u9801");
237
+ var _this$props6 = this.props,
238
+ bookmarks = _this$props6.bookmarks,
239
+ total = _this$props6.total;
240
+ return /*#__PURE__*/_react["default"].createElement(Container, null, /*#__PURE__*/_react["default"].createElement(_bookmarks["default"], {
241
+ bookmarks: bookmarks,
242
+ handleDelete: this.handleDeleteButtonClicked,
243
+ total: total
244
+ }), /*#__PURE__*/_react["default"].createElement(MoreContainer, {
245
+ hasMore: bookmarks.length < total
246
+ }, /*#__PURE__*/_react["default"].createElement(_more["default"], {
247
+ loadMore: this.loadMoreBookmarks
248
+ }, /*#__PURE__*/_react["default"].createElement("span", null, text.loadMore))), /*#__PURE__*/_react["default"].createElement(_CSSTransition["default"], {
249
+ classNames: transitionName,
250
+ "in": this.state.showConfirmation,
251
+ timeout: {
252
+ enter: transitionDuration.enter,
253
+ exit: transitionDuration.leave
254
+ },
255
+ mountOnEnter: true,
256
+ unmountOnExit: true
257
+ }, /*#__PURE__*/_react["default"].createElement(_confirmation["default"], {
258
+ onCancel: this.hideComfirmation,
259
+ onConfirm: this.handleDeletingConfirmed,
260
+ content: text.dialog.content,
261
+ confirm: text.dialog.confirm,
262
+ cancel: text.dialog.cancel
263
+ })));
264
+ }
265
+ }]);
266
+
267
+ return BookmarkList;
268
+ }(_react["default"].Component);
269
+
270
+ BookmarkList.propTypes = {
271
+ // Props below are provided by redux
272
+ bookmarks: _propTypes2["default"].arrayOf(_propTypes["default"].bookmark).isRequired,
273
+ total: _propTypes2["default"].number.isRequired,
274
+ getMultipleBookmarks: _propTypes2["default"].func.isRequired,
275
+ deleteSingleBookmark: _propTypes2["default"].func.isRequired,
276
+ isAuthed: _propTypes2["default"].bool.isRequired,
277
+ jwt: _propTypes2["default"].string.isRequired,
278
+ userID: _propTypes2["default"].number.isRequired
279
+ };
280
+
281
+ var mapStateToProps = function mapStateToProps(state) {
282
+ var bookmarkIDList = _.get(state, [reduxStatePropKeys.bookmarks, 'bookmarkIDList'], []);
283
+
284
+ var bookmarkEntities = _.get(state, [reduxStatePropKeys.bookmarks, 'entities'], {});
285
+
286
+ var bookmarks = _.map(bookmarkIDList, function (id) {
287
+ return _.get(bookmarkEntities, id);
288
+ });
289
+
290
+ var total = _.get(state, [reduxStatePropKeys.bookmarks, 'total'], 0);
291
+
292
+ var jwt = _.get(state, [reduxStatePropKeys.auth, 'accessToken']);
293
+
294
+ var userID = _.get(state, [reduxStatePropKeys.auth, 'userInfo', 'user_id']);
295
+
296
+ var isAuthed = _.get(state, [reduxStatePropKeys.auth, 'isAuthed']);
297
+
298
+ return {
299
+ bookmarks: bookmarks,
300
+ isAuthed: isAuthed,
301
+ jwt: jwt,
302
+ total: total,
303
+ userID: userID
304
+ };
305
+ };
306
+
307
+ var _default = (0, _reactRedux.connect)(mapStateToProps, {
308
+ getMultipleBookmarks: getMultipleBookmarks,
309
+ deleteSingleBookmark: deleteSingleBookmark
310
+ })(BookmarkList);
311
+
312
+ exports["default"] = _default;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports["default"] = void 0;
7
+
8
+ var _propTypes = _interopRequireDefault(require("prop-types"));
9
+
10
+ var _react = _interopRequireDefault(require("react"));
11
+
12
+ var _styledComponents = _interopRequireDefault(require("styled-components"));
13
+
14
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
15
+
16
+ var Container = /*#__PURE__*/_styledComponents["default"].div.withConfig({
17
+ displayName: "redirect-to-sign-in__Container",
18
+ componentId: "sc-1b4wjsc-0"
19
+ })(["height:80vh;display:flex;justify-content:center;align-items:center;"]);
20
+
21
+ var Message = /*#__PURE__*/_styledComponents["default"].div.withConfig({
22
+ displayName: "redirect-to-sign-in__Message",
23
+ componentId: "sc-1b4wjsc-1"
24
+ })(["width:90%;text-align:center;"]);
25
+
26
+ var RedirectToSignIn = function RedirectToSignIn(_ref) {
27
+ var children = _ref.children;
28
+ return /*#__PURE__*/_react["default"].createElement(Container, null, /*#__PURE__*/_react["default"].createElement(Message, null, children));
29
+ };
30
+
31
+ RedirectToSignIn.propTypes = {
32
+ children: _propTypes["default"].node
33
+ };
34
+ var _default = RedirectToSignIn;
35
+ exports["default"] = _default;
@@ -0,0 +1,259 @@
1
+ "use strict";
2
+
3
+ function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports["default"] = void 0;
9
+
10
+ var _reactRedux = require("react-redux");
11
+
12
+ var _signInHref = require("@twreporter/core/lib/utils/sign-in-href");
13
+
14
+ var _propTypes = _interopRequireDefault(require("@twreporter/core/lib/constants/prop-types"));
15
+
16
+ var _propTypes2 = _interopRequireDefault(require("prop-types"));
17
+
18
+ var _react = _interopRequireDefault(require("react"));
19
+
20
+ var _redux = _interopRequireDefault(require("@twreporter/redux"));
21
+
22
+ var _get = _interopRequireDefault(require("lodash/get"));
23
+
24
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
25
+
26
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
27
+
28
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
29
+
30
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
31
+
32
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
33
+
34
+ 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); } }
35
+
36
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
37
+
38
+ function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
39
+
40
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
41
+
42
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
43
+
44
+ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
45
+
46
+ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
47
+
48
+ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
49
+
50
+ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
51
+
52
+ var _ = {
53
+ get: _get["default"]
54
+ };
55
+ var _twreporterRedux$acti = _redux["default"].actions,
56
+ createSingleBookmark = _twreporterRedux$acti.createSingleBookmark,
57
+ deleteSingleBookmark = _twreporterRedux$acti.deleteSingleBookmark,
58
+ getSingleBookmark = _twreporterRedux$acti.getSingleBookmark;
59
+ var reduxStatePropKeys = _redux["default"].reduxStateFields;
60
+
61
+ function getHostFromWindowLocation() {
62
+ var defaultHost = 'https://www.twreporter.org';
63
+
64
+ try {
65
+ var _window$location = window.location,
66
+ host = _window$location.host,
67
+ protocol = _window$location.protocol;
68
+
69
+ if (host && protocol) {
70
+ return "".concat(protocol, "//").concat(host);
71
+ } else {
72
+ console.warn('The host or protocol in `window.location` is not valid:', 'window.location.protocol:', protocol, 'window.location.host:', host, "Return default host '".concat(defaultHost, "' instead."));
73
+ return defaultHost;
74
+ }
75
+ } catch (err) {
76
+ console.warn('Error on getting `host` and `protocol` from `window.location`:', err);
77
+ }
78
+ }
79
+
80
+ var BookmarkWidget = /*#__PURE__*/function (_React$PureComponent) {
81
+ _inherits(BookmarkWidget, _React$PureComponent);
82
+
83
+ var _super = _createSuper(BookmarkWidget);
84
+
85
+ function BookmarkWidget(props) {
86
+ var _this;
87
+
88
+ _classCallCheck(this, BookmarkWidget);
89
+
90
+ _this = _super.call(this, props);
91
+ _this.addCurrentPageToBookmarks = _this.addCurrentPageToBookmarks.bind(_assertThisInitialized(_this));
92
+ _this.removeCurrentPageFromBookmarks = _this.removeCurrentPageFromBookmarks.bind(_assertThisInitialized(_this));
93
+ return _this;
94
+ }
95
+
96
+ _createClass(BookmarkWidget, [{
97
+ key: "componentDidMount",
98
+ value: function componentDidMount() {
99
+ /* TODO: Implement `status` for bookmark widget in redux reducer and action:
100
+ There should be different states below for the bookmark widget status of an article:
101
+ unknown: It has not checked the bookmark status yet
102
+ isChecking: The request to check was made but has not gotten the response yet
103
+ bookmarked: The article is bookmarked
104
+ notBookmarked: The article is not bookmarked
105
+ invalid: There's an error or there's no valid authentication info
106
+ The current code does not distinguish the `unknown`, `notBookmarked`, `isChecking`, and `invalid` situation.
107
+ The best result is that we only send request to check bookmark when the status is `unknown`.
108
+ But now we send request when there's no bookmark data for this component in the redux store when `componentDidMount`, no matter what's the reason of it.
109
+ */
110
+ var articleSlug = _.get(this.props, 'articleMeta.slug');
111
+
112
+ if (articleSlug && typeof articleSlug === 'string') {
113
+ var _this$props = this.props,
114
+ isAuthed = _this$props.isAuthed,
115
+ toAutoCheck = _this$props.toAutoCheck;
116
+
117
+ if (isAuthed && toAutoCheck && !this.checkIfThisArticleBookmarked()) {
118
+ var _this$props2 = this.props,
119
+ jwt = _this$props2.jwt,
120
+ userID = _this$props2.userID,
121
+ _getSingleBookmark = _this$props2.getSingleBookmark;
122
+
123
+ _getSingleBookmark(jwt, userID, articleSlug, getHostFromWindowLocation());
124
+ }
125
+ } else {
126
+ console.error('`this.props.articleMeta.slug` must be an unempty string, but is', articleSlug);
127
+ }
128
+ }
129
+ }, {
130
+ key: "redirectToLoginPageIfNotAuthorized",
131
+ value: function redirectToLoginPageIfNotAuthorized() {
132
+ var _this$props3 = this.props,
133
+ isAuthed = _this$props3.isAuthed,
134
+ jwt = _this$props3.jwt;
135
+
136
+ if (!isAuthed || !jwt) {
137
+ var currentHref = typeof window === 'undefined' ? '' : window.location.href;
138
+ window.location.href = (0, _signInHref.getSignInHref)(currentHref);
139
+ }
140
+ }
141
+ }, {
142
+ key: "addCurrentPageToBookmarks",
143
+ value: function addCurrentPageToBookmarks() {
144
+ this.redirectToLoginPageIfNotAuthorized();
145
+ var _this$props4 = this.props,
146
+ jwt = _this$props4.jwt,
147
+ userID = _this$props4.userID,
148
+ createSingleBookmark = _this$props4.createSingleBookmark,
149
+ articleMeta = _this$props4.articleMeta;
150
+
151
+ var bookmarkToBeCreated = _objectSpread(_objectSpread({}, articleMeta), {}, {
152
+ host: getHostFromWindowLocation()
153
+ });
154
+
155
+ return createSingleBookmark(jwt, userID, bookmarkToBeCreated);
156
+ }
157
+ }, {
158
+ key: "removeCurrentPageFromBookmarks",
159
+ value: function removeCurrentPageFromBookmarks() {
160
+ this.redirectToLoginPageIfNotAuthorized();
161
+ var _this$props5 = this.props,
162
+ jwt = _this$props5.jwt,
163
+ userID = _this$props5.userID,
164
+ deleteSingleBookmark = _this$props5.deleteSingleBookmark,
165
+ bookmark = _this$props5.bookmark;
166
+
167
+ var bookmarkID = _.get(bookmark, 'id');
168
+
169
+ if (bookmarkID) {
170
+ deleteSingleBookmark(jwt, userID, bookmarkID);
171
+ } else {
172
+ console.error('Error on deleting bookmark with `BookmarkWidget`: No valid bookmark id.');
173
+ }
174
+ }
175
+ }, {
176
+ key: "checkIfThisArticleBookmarked",
177
+ value: function checkIfThisArticleBookmarked() {
178
+ var bookmark = this.props.bookmark;
179
+ var isClient = typeof window !== 'undefined';
180
+
181
+ if (bookmark && isClient) {
182
+ var hostFromWindow = getHostFromWindowLocation();
183
+
184
+ if (_.get(bookmark, 'host') !== hostFromWindow) {
185
+ /* Only check the consistency of `host` when client-side rendering. */
186
+ console.warn('Warning on checking bookmark status in `BookmarkWidget`:', 'The `host` in the bookmark data is diffrent from the `host` in current `window`.', 'host in bookmark:', bookmark.host, 'host in `window.location`:', hostFromWindow);
187
+ }
188
+ }
189
+
190
+ return Boolean(bookmark);
191
+ }
192
+ }, {
193
+ key: "render",
194
+ value: function render() {
195
+ var articleMeta = this.props.articleMeta;
196
+ var slug = articleMeta.slug;
197
+
198
+ if (!slug) {
199
+ return null;
200
+ }
201
+
202
+ var isBookmarked = this.checkIfThisArticleBookmarked();
203
+ var renderIcon = this.props.renderIcon;
204
+ return typeof renderIcon === 'function' ? renderIcon(isBookmarked, this.addCurrentPageToBookmarks, this.removeCurrentPageFromBookmarks) : null;
205
+ }
206
+ }]);
207
+
208
+ return BookmarkWidget;
209
+ }(_react["default"].PureComponent);
210
+
211
+ BookmarkWidget.defaultProps = {
212
+ articleMeta: {},
213
+ bookmark: null,
214
+ isAuthed: false,
215
+ jwt: '',
216
+ userID: NaN,
217
+ toAutoCheck: true
218
+ };
219
+ BookmarkWidget.propTypes = {
220
+ articleMeta: _propTypes["default"].articleMetaForBookmark,
221
+ // Props below are provided by redux
222
+ bookmark: _propTypes["default"].bookmark,
223
+ createSingleBookmark: _propTypes2["default"].func.isRequired,
224
+ deleteSingleBookmark: _propTypes2["default"].func.isRequired,
225
+ getSingleBookmark: _propTypes2["default"].func.isRequired,
226
+ isAuthed: _propTypes2["default"].bool,
227
+ jwt: _propTypes2["default"].string,
228
+ userID: _propTypes2["default"].number,
229
+ renderIcon: _propTypes2["default"].func.isRequired,
230
+ toAutoCheck: _propTypes2["default"].bool
231
+ };
232
+
233
+ function mapStateToProps(state, ownProps) {
234
+ var currentSlug = _.get(ownProps, 'articleMeta.slug');
235
+
236
+ var jwt = _.get(state, [reduxStatePropKeys.auth, 'accessToken']);
237
+
238
+ var userID = _.get(state, [reduxStatePropKeys.auth, 'userInfo', 'user_id']);
239
+
240
+ var isAuthed = _.get(state, [reduxStatePropKeys.auth, 'isAuthed']);
241
+
242
+ var bookmarkInStore = _.get(state, [reduxStatePropKeys.bookmarkWidget, 'bookmark']);
243
+
244
+ var bookmarkForThisWidget = currentSlug && currentSlug === _.get(bookmarkInStore, 'slug') ? bookmarkInStore : null;
245
+ return {
246
+ bookmark: bookmarkForThisWidget,
247
+ isAuthed: isAuthed,
248
+ jwt: jwt,
249
+ userID: userID
250
+ };
251
+ }
252
+
253
+ var _default = (0, _reactRedux.connect)(mapStateToProps, {
254
+ getSingleBookmark: getSingleBookmark,
255
+ createSingleBookmark: createSingleBookmark,
256
+ deleteSingleBookmark: deleteSingleBookmark
257
+ })(BookmarkWidget);
258
+
259
+ exports["default"] = _default;