@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.
- package/CHANGELOG.md +544 -0
- package/LICENSE +21 -0
- package/README.md +46 -0
- package/lib/bookmark-list/bookmark.js +251 -0
- package/lib/bookmark-list/bookmarks.js +93 -0
- package/lib/bookmark-list/customized-link.js +45 -0
- package/lib/bookmark-list/image-wrapper.js +119 -0
- package/lib/bookmark-list/index.js +312 -0
- package/lib/bookmark-list/redirect-to-sign-in.js +35 -0
- package/lib/bookmark-widget/index.js +259 -0
- package/lib/confirmation/index.js +125 -0
- package/lib/donation-link.js +75 -0
- package/lib/error/index.js +17 -0
- package/lib/error/message.js +567 -0
- package/lib/footer/constants/paths.js +8 -0
- package/lib/footer/constants/styles.js +81 -0
- package/lib/footer/content.js +227 -0
- package/lib/footer/icon-list.js +191 -0
- package/lib/footer/index.js +123 -0
- package/lib/footer/logo.js +92 -0
- package/lib/is-fetching-wrapper.js +126 -0
- package/lib/link-with-tracker.js +153 -0
- package/lib/listing-page/components/image.js +185 -0
- package/lib/listing-page/components/list-item.js +197 -0
- package/lib/listing-page/components/list.js +188 -0
- package/lib/listing-page/components/topics/index.js +215 -0
- package/lib/listing-page/components/topics/page-content.js +44 -0
- package/lib/listing-page/components/topics/post-item.js +139 -0
- package/lib/listing-page/components/topics/posts.js +24 -0
- package/lib/listing-page/components/topics/section.js +104 -0
- package/lib/listing-page/components/topics/topic-item.js +206 -0
- package/lib/listing-page/constants/mockup-spec.js +39 -0
- package/lib/listing-page/constants/predefined-css.js +21 -0
- package/lib/listing-page/constants/topics.js +13 -0
- package/lib/listing-page/index.js +30 -0
- package/lib/mobile-pop-up-modal.js +161 -0
- package/lib/more.js +98 -0
- package/lib/pagination/index.js +310 -0
- package/lib/podcast-link.js +73 -0
- package/lib/side-bar/index.js +317 -0
- package/lib/table-of-contents/index.js +532 -0
- package/lib/utils/link-with-params.js +27 -0
- 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;
|