PluginProbe ʕ •ᴥ•ʔ
Presto Player / 4.3.3
Presto Player v4.3.3
4.4.0 4.3.3 4.3.2 4.3.1 4.3.0 4.2.4 4.2.3 4.2.2 4.2.0 4.2.1 trunk 1.10.0 1.10.1 1.10.2 1.11.0 1.12.0 1.13.0 1.14.0 1.14.1 1.5.10 1.5.11 1.5.12 1.5.13 1.5.14 1.5.15 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.10 1.6.11 1.6.12 1.6.13 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.11 2.0.12 2.0.13 2.0.14 2.0.15 2.0.16 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.2.0 2.2.1 2.2.2 2.2.3 2.2.3-beta1 2.3.0 2.3.1 2.3.2 2.3.3 3.0.0 3.0.0-beta1 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.1.0 3.1.1 3.1.2 3.1.3 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.0.8 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4
presto-player / src / admin / dashboard / components / WhatsNew / useWhatsNewRSS.js
presto-player / src / admin / dashboard / components / WhatsNew Last commit date
index.js 3 months ago useWhatsNewRSS.js 3 months ago
useWhatsNewRSS.js
1287 lines
1 /**
2 * === Whats New RSS ===
3 *
4 * Version: 1.0.7
5 * Generated on: 4th December, 2024
6 * Documentation: https://github.com/brainstormforce/whats-new-rss/blob/master/README.md
7 */
8
9 import { useEffect, useRef } from "react";
10 var __assign =
11 (this && this.__assign) ||
12 function () {
13 __assign =
14 Object.assign ||
15 function (t) {
16 for (var s, i = 1, n = arguments.length; i < n; i++) {
17 s = arguments[i];
18 for (var p in s)
19 if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
20 }
21 return t;
22 };
23 return __assign.apply(this, arguments);
24 };
25 var __awaiter =
26 (this && this.__awaiter) ||
27 function (thisArg, _arguments, P, generator) {
28 function adopt(value) {
29 return value instanceof P
30 ? value
31 : new P(function (resolve) {
32 resolve(value);
33 });
34 }
35 return new (P || (P = Promise))(function (resolve, reject) {
36 function fulfilled(value) {
37 try {
38 step(generator.next(value));
39 } catch (e) {
40 reject(e);
41 }
42 }
43 function rejected(value) {
44 try {
45 step(generator["throw"](value));
46 } catch (e) {
47 reject(e);
48 }
49 }
50 function step(result) {
51 result.done
52 ? resolve(result.value)
53 : adopt(result.value).then(fulfilled, rejected);
54 }
55 step((generator = generator.apply(thisArg, _arguments || [])).next());
56 });
57 };
58 var __generator =
59 (this && this.__generator) ||
60 function (thisArg, body) {
61 var _ = {
62 label: 0,
63 sent: function () {
64 if (t[0] & 1) throw t[1];
65 return t[1];
66 },
67 trys: [],
68 ops: [],
69 },
70 f,
71 y,
72 t,
73 g = Object.create(
74 (typeof Iterator === "function" ? Iterator : Object).prototype
75 );
76 return (
77 (g.next = verb(0)),
78 (g["throw"] = verb(1)),
79 (g["return"] = verb(2)),
80 typeof Symbol === "function" &&
81 (g[Symbol.iterator] = function () {
82 return this;
83 }),
84 g
85 );
86 function verb(n) {
87 return function (v) {
88 return step([n, v]);
89 };
90 }
91 function step(op) {
92 if (f) throw new TypeError("Generator is already executing.");
93 while ((g && ((g = 0), op[0] && (_ = 0)), _))
94 try {
95 if (
96 ((f = 1),
97 y &&
98 (t =
99 op[0] & 2
100 ? y["return"]
101 : op[0]
102 ? y["throw"] || ((t = y["return"]) && t.call(y), 0)
103 : y.next) &&
104 !(t = t.call(y, op[1])).done)
105 )
106 return t;
107 if (((y = 0), t)) op = [op[0] & 2, t.value];
108 switch (op[0]) {
109 case 0:
110 case 1:
111 t = op;
112 break;
113 case 4:
114 _.label++;
115 return { value: op[1], done: false };
116 case 5:
117 _.label++;
118 y = op[1];
119 op = [0];
120 continue;
121 case 7:
122 op = _.ops.pop();
123 _.trys.pop();
124 continue;
125 default:
126 if (
127 !((t = _.trys), (t = t.length > 0 && t[t.length - 1])) &&
128 (op[0] === 6 || op[0] === 2)
129 ) {
130 _ = 0;
131 continue;
132 }
133 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) {
134 _.label = op[1];
135 break;
136 }
137 if (op[0] === 6 && _.label < t[1]) {
138 _.label = t[1];
139 t = op;
140 break;
141 }
142 if (t && _.label < t[2]) {
143 _.label = t[2];
144 _.ops.push(op);
145 break;
146 }
147 if (t[2]) _.ops.pop();
148 _.trys.pop();
149 continue;
150 }
151 op = body.call(thisArg, _);
152 } catch (e) {
153 op = [6, e];
154 y = 0;
155 } finally {
156 f = t = 0;
157 }
158 if (op[0] & 5) throw op[1];
159 return { value: op[0] ? op[1] : void 0, done: true };
160 }
161 };
162 var WhatsNewRSSDefaultArgs = {
163 rssFeedURL: "",
164 selector: "",
165 uniqueKey: "",
166 loaderIcon:
167 '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">\n\t<circle cx="50" cy="50" fill="none" stroke="#9f9f9f" stroke-width="10" r="35" stroke-dasharray="164.93361431346415 56.97787143782138">\n\t\t<animateTransform attributeName="transform" type="rotate" repeatCount="indefinite" dur="1s" values="0 50 50;360 50 50" keyTimes="0;1"></animateTransform>\n\t</circle>\n\t</svg>',
168 viewAll: {
169 link: "",
170 label: "View All",
171 },
172 triggerButton: {
173 label: "",
174 icon: '<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M8.61703 13.1998C8.04294 13.1503 7.46192 13.125 6.875 13.125H6.25C4.17893 13.125 2.5 11.4461 2.5 9.375C2.5 7.30393 4.17893 5.625 6.25 5.625H6.875C7.46192 5.625 8.04294 5.59972 8.61703 5.55018M8.61703 13.1998C8.82774 14.0012 9.1031 14.7764 9.43719 15.5195C9.64341 15.9782 9.48685 16.5273 9.05134 16.7787L8.50441 17.0945C8.04492 17.3598 7.45466 17.1921 7.23201 16.7106C6.70983 15.5811 6.30451 14.3866 6.03155 13.1425M8.61703 13.1998C8.29598 11.9787 8.125 10.6968 8.125 9.375C8.125 8.05316 8.29598 6.77125 8.61703 5.55018M8.61703 13.1998C11.25 13.427 13.737 14.1643 15.9789 15.3124M8.61703 5.55018C11.25 5.323 13.737 4.58569 15.9789 3.43757M15.9789 3.43757C15.8808 3.12162 15.7751 2.80903 15.662 2.5M15.9789 3.43757C16.4247 4.87356 16.7131 6.37885 16.8238 7.93326M15.9789 15.3124C15.8808 15.6284 15.7751 15.941 15.662 16.25M15.9789 15.3124C16.4247 13.8764 16.7131 12.3711 16.8238 10.8167M16.8238 7.93326C17.237 8.2772 17.5 8.79539 17.5 9.375C17.5 9.95461 17.237 10.4728 16.8238 10.8167M16.8238 7.93326C16.8578 8.40942 16.875 8.8902 16.875 9.375C16.875 9.8598 16.8578 10.3406 16.8238 10.8167" stroke="#94A3B8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',
175 beforeBtn: "",
176 afterBtn: "",
177 className: "",
178 onClick: function () {},
179 },
180 notification: {
181 setLastPostUnixTime: null,
182 getLastPostUnixTime: null,
183 },
184 flyout: {
185 title: "What's New?",
186 innerContent: {
187 titleLink: true,
188 additionalClasses: [],
189 },
190 excerpt: {
191 wordLimit: 500,
192 moreSymbol: "&hellip;",
193 readMore: {
194 label: "Read More",
195 className: "",
196 },
197 },
198 className: "",
199 closeOnEsc: true,
200 closeOnOverlayClick: true,
201 closeBtnIcon:
202 '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M6 18L18 6M6 6L18 18" stroke="#94A3B8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',
203 formatDate: null,
204 onOpen: function () {},
205 onClose: function () {},
206 onReady: function () {},
207 },
208 };
209 var WhatsNewRSS = /** @class */ (function () {
210 /**
211 * Initialize our class.
212 *
213 * @param {ConstructorArgs} args
214 */
215 function WhatsNewRSS(args) {
216 this.rssFeedURLs = [];
217 /**
218 * UnixTime stamp of the last seen or read post.
219 */
220 this.lastPostUnixTime = 0;
221 /**
222 * UnixTime stamp of the last seen or read post for multi feeds by feed key.
223 */
224 this.multiLastPostUnixTime = {};
225 /**
226 * Total number of new notification counts.
227 */
228 this.notificationsCount = 0;
229 /**
230 * Notification counts for multi feeds by feed key.
231 */
232 this.multiNotificationCount = {};
233 /**
234 * Check if has new feeds.
235 */
236 this.hasNewFeeds = false;
237 /**
238 * Check if has new feeds in multi feeds mode.
239 */
240 this.multiHasNewFeeds = {};
241 this.validateArgs(args);
242 this.parseDefaults(args);
243 this.setElement();
244 if (!this.getElement()) {
245 console.warn("WNR: Cannot find element with", this.getArgs().selector);
246 return;
247 }
248 this.setID();
249 this.setRSSFeedURLs();
250 WhatsNewRSSCacheUtils.setInstanceID(this.getID());
251 this.RSS_Fetch_Instance = new WhatsNewRSSFetch(this);
252 this.RSS_View_Instance = new WhatsNewRSSView(this);
253 this.setNotificationsCount();
254 this.setTriggers();
255 }
256 /**
257 * Validate the passed arguments in constructor.
258 *
259 * @param {ConstructorArgs} args
260 */
261 WhatsNewRSS.prototype.validateArgs = function (args) {
262 ["rssFeedURL", "selector", "uniqueKey"].forEach(function (requiredArg) {
263 if (!args[requiredArg]) {
264 throw new Error(
265 "".concat(
266 requiredArg,
267 " is a required argument. It cannot be empty or undefined."
268 )
269 );
270 }
271 switch (requiredArg) {
272 case "rssFeedURL":
273 var arg = args[requiredArg];
274 if (Array.isArray(arg)) {
275 arg.forEach(function (rssFeedURL) {
276 if (
277 !(rssFeedURL === null || rssFeedURL === void 0
278 ? void 0
279 : rssFeedURL.key)
280 ) {
281 throw new Error(
282 'The parameter "key" is required for "'.concat(
283 requiredArg,
284 '" parameter in multi-feed mode.'
285 )
286 );
287 }
288 if (rssFeedURL.key.includes(" ")) {
289 throw new Error(
290 'The parameter "key" cannot have spaces for "'
291 .concat(
292 requiredArg,
293 '" parameter in multi-feed mode. Ref Key: "'
294 )
295 .concat(rssFeedURL.key, '"')
296 );
297 }
298 });
299 }
300 break;
301 default:
302 break;
303 }
304 });
305 };
306 /**
307 * Parse the arguments passed by the user with the defaults.
308 *
309 * @param {ConstructorArgs} args
310 */
311 WhatsNewRSS.prototype.parseDefaults = function (args) {
312 var _a, _b;
313 this.args = __assign(__assign(__assign({}, WhatsNewRSSDefaultArgs), args), {
314 viewAll: __assign(
315 __assign({}, WhatsNewRSSDefaultArgs.viewAll),
316 args === null || args === void 0 ? void 0 : args.viewAll
317 ),
318 triggerButton: __assign(
319 __assign({}, WhatsNewRSSDefaultArgs.triggerButton),
320 args === null || args === void 0 ? void 0 : args.triggerButton
321 ),
322 flyout: __assign(
323 __assign(
324 __assign({}, WhatsNewRSSDefaultArgs.flyout),
325 args === null || args === void 0 ? void 0 : args.flyout
326 ),
327 {
328 innerContent: __assign(
329 __assign({}, WhatsNewRSSDefaultArgs.flyout.innerContent),
330 (_a = args === null || args === void 0 ? void 0 : args.flyout) ===
331 null || _a === void 0
332 ? void 0
333 : _a.innerContent
334 ),
335 excerpt: __assign(
336 __assign({}, WhatsNewRSSDefaultArgs.flyout.excerpt),
337 (_b = args === null || args === void 0 ? void 0 : args.flyout) ===
338 null || _b === void 0
339 ? void 0
340 : _b.excerpt
341 ),
342 }
343 ),
344 });
345 };
346 /**
347 * Returns parsed args.
348 *
349 * @returns {ConstructorArgs}
350 */
351 WhatsNewRSS.prototype.getArgs = function () {
352 return this.args;
353 };
354 /**
355 * Sets the HTML element queried using passed selector.
356 */
357 WhatsNewRSS.prototype.setElement = function () {
358 this.element = document.querySelector(this.args.selector);
359 };
360 /**
361 * Returns the html element according to the selector.
362 *
363 * @returns {HTMLElement}
364 */
365 WhatsNewRSS.prototype.getElement = function () {
366 return this.element;
367 };
368 /**
369 * Creates unique ID for current instance, that can be used by the library elements.
370 */
371 WhatsNewRSS.prototype.setID = function () {
372 var data = [this.getArgs().selector, this.getArgs().uniqueKey];
373 var rssFeedURL = this.getArgs().rssFeedURL;
374 if (Array.isArray(rssFeedURL)) {
375 rssFeedURL.forEach(function (_rssFeedURL) {
376 data.push(_rssFeedURL.key);
377 });
378 } else {
379 data.push(rssFeedURL);
380 }
381 this.ID =
382 btoa(data.join("-")).slice(-12).replace(/=/g, "") +
383 "-" +
384 this.getArgs().uniqueKey;
385 };
386 /**
387 * Whether or not multiple feed urls is provided or not.
388 *
389 * @returns {boolean}
390 */
391 WhatsNewRSS.prototype.isMultiFeedRSS = function () {
392 return "string" !== typeof this.getArgs().rssFeedURL;
393 };
394 WhatsNewRSS.prototype.setRSSFeedURLs = function () {
395 var _this = this;
396 var rssFeedURL = this.getArgs().rssFeedURL;
397 if (!this.isMultiFeedRSS()) {
398 this.rssFeedURLs.push({
399 key: null,
400 label: "",
401 url: rssFeedURL.toString(),
402 });
403 } else {
404 if (Array.isArray(rssFeedURL)) {
405 rssFeedURL.forEach(function (_item) {
406 _this.rssFeedURLs.push(_item);
407 });
408 }
409 }
410 };
411 WhatsNewRSS.prototype.getRSSFeedURLs = function () {
412 return this.rssFeedURLs;
413 };
414 /**
415 * Returns the current instance unique ID.
416 *
417 * @returns {string}
418 */
419 WhatsNewRSS.prototype.getID = function () {
420 return this.ID;
421 };
422 /**
423 * Checks and counts new notification for the notification badge.
424 */
425 WhatsNewRSS.prototype.setNotificationsCount = function () {
426 return __awaiter(this, void 0, void 0, function () {
427 var _this = this;
428 return __generator(this, function (_a) {
429 switch (_a.label) {
430 case 0:
431 return [
432 4 /*yield*/,
433 Promise.all(
434 this.getRSSFeedURLs().map(function (_a) {
435 return __awaiter(_this, [_a], void 0, function (_b) {
436 var lastPostUnixTime;
437 var key = _b.key;
438 return __generator(this, function (_c) {
439 switch (_c.label) {
440 case 0:
441 lastPostUnixTime = 0;
442 if (
443 !(
444 "function" ===
445 typeof this.getArgs().notification
446 .getLastPostUnixTime
447 )
448 )
449 return [3 /*break*/, 2];
450 return [
451 4 /*yield*/,
452 this.getArgs().notification.getLastPostUnixTime(
453 key,
454 this
455 ),
456 ];
457 case 1:
458 lastPostUnixTime = _c.sent();
459 return [3 /*break*/, 3];
460 case 2:
461 lastPostUnixTime =
462 WhatsNewRSSCacheUtils.getLastPostUnixTime(key);
463 _c.label = 3;
464 case 3:
465 if (this.isMultiFeedRSS()) {
466 this.multiLastPostUnixTime[key] = +lastPostUnixTime;
467 } else {
468 this.lastPostUnixTime = +lastPostUnixTime;
469 }
470 return [2 /*return*/];
471 }
472 });
473 });
474 })
475 ),
476 ];
477 case 1:
478 _a.sent();
479 return [
480 4 /*yield*/,
481 this.RSS_Fetch_Instance.fetchData()
482 .then(function (res) {
483 Object.keys(res).forEach(function (key) {
484 var data = res[key];
485 if (!data.length) {
486 return;
487 }
488 _this.multiNotificationCount[key] = 0;
489 var currentPostUnixTime = +data[0].date;
490 var lastPostUnixTime = _this.isMultiFeedRSS()
491 ? _this.multiLastPostUnixTime[key]
492 : _this.lastPostUnixTime;
493 if (currentPostUnixTime > lastPostUnixTime) {
494 data.forEach(function (item) {
495 if (item.date > lastPostUnixTime) {
496 if (_this.isMultiFeedRSS()) {
497 _this.multiNotificationCount[key]++;
498 _this.multiHasNewFeeds[key] = true;
499 }
500 // Keep a record of total notifications even in multi-feed mode.
501 _this.notificationsCount++;
502 _this.hasNewFeeds = true;
503 }
504 });
505 _this.RSS_View_Instance.setNotification(
506 _this.notificationsCount
507 );
508 }
509 });
510 })
511 .catch(console.error),
512 ];
513 case 2:
514 _a.sent();
515 return [2 /*return*/];
516 }
517 });
518 });
519 };
520 /**
521 * Returns total number of new notifications.
522 *
523 * @returns {number}
524 */
525 WhatsNewRSS.prototype.getNotificationsCount = function () {
526 return this.notificationsCount;
527 };
528 /**
529 * Sets the triggers for the library, eg: close, open, fetch.
530 */
531 WhatsNewRSS.prototype.setTriggers = function () {
532 var _this = this;
533 var triggerButton = document.getElementById(
534 this.RSS_View_Instance.getTriggerButtonID()
535 );
536 var flyout = document.getElementById(this.RSS_View_Instance.getFlyoutID());
537 var flyoutInner = flyout.querySelector(
538 ".whats-new-rss-flyout-inner-content"
539 );
540 var flyoutCloseBtn = document.getElementById(
541 this.RSS_View_Instance.getFlyoutCloseBtnID()
542 );
543 var multiFeedNav = document.getElementById(
544 this.RSS_View_Instance.getFlyoutMultiFeedNavID()
545 );
546 var injectContents = function (key) {
547 /**
548 * Fetch data on flyout open.
549 */
550 _this.RSS_Fetch_Instance.fetchData()
551 .then(function (res) {
552 flyoutInner.innerHTML = "";
553 var data = res[key];
554 if (!data.length) {
555 return;
556 }
557 var currentPostUnixTime = +data[0].date;
558 var lastPostUnixTime = _this.isMultiFeedRSS()
559 ? _this.multiLastPostUnixTime[key]
560 : _this.lastPostUnixTime;
561 data.forEach(function (item) {
562 var isNewPost = !!lastPostUnixTime
563 ? item.date > lastPostUnixTime
564 : false;
565 var contentTitle = _this.getArgs().flyout.innerContent.titleLink
566 ? '<a href="'
567 .concat(
568 item.postLink,
569 '" target="_blank">\n\t\t\t\t\t\t\t\t<h2>'
570 )
571 .concat(item.title, "</h2>\n\t\t\t\t\t\t\t</a>")
572 : "<h2>".concat(item.title, "</h2>");
573 var innerContent =
574 '\n\t\t\t\t\t\t\t\t<div class="rss-content-header">\n\t\t\t\t\t\t\t\t\t<p>'
575 .concat(
576 _this.RSS_View_Instance.formatDate(new Date(item.date)),
577 "</p>\n\t\t\t\t\t\t\t\t\t"
578 )
579 .concat(
580 contentTitle,
581 "\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t"
582 )
583 .concat(
584 _this.RSS_View_Instance.createExcerpt(
585 item.description,
586 item.postLink,
587 _this.getArgs().flyout.excerpt
588 ),
589 "\n\t\t\t\t\t\t\t\t"
590 )
591 .concat(
592 _this.RSS_View_Instance.listChildrenPosts(item.children),
593 "\n\t\t\t\t\t\t\t"
594 );
595 var additionalClasses =
596 _this.getArgs().flyout.innerContent.additionalClasses;
597 if (!!key) {
598 additionalClasses.push("`inner-content-item-feed-key-${key}`");
599 }
600 flyoutInner.innerHTML +=
601 _this.RSS_View_Instance.innerContentWrapper(
602 innerContent,
603 isNewPost,
604 additionalClasses.join(" ")
605 );
606 });
607 if (_this.getArgs().viewAll.link) {
608 // If we have link provided for the view all button then append a view all button at the end of the contents.
609 flyoutInner.innerHTML +=
610 _this.RSS_View_Instance.innerContentWrapper(
611 '\n\t\t\t\t\t\t\t<a href="'
612 .concat(
613 _this.getArgs().viewAll.link,
614 '" class="button view-all">'
615 )
616 .concat(_this.getArgs().viewAll.label, "</a>\n\t\t\t\t\t\t\t")
617 );
618 }
619 _this.RSS_View_Instance.setIsLoading(false);
620 flyout.classList.add("ready");
621 _this.getArgs().flyout.onReady(_this);
622 /**
623 * Change focus to flyout on flyout ready.
624 */
625 flyout.focus();
626 // Set the last latest post date for notification handling.
627 if (!_this.isMultiFeedRSS()) {
628 _this.lastPostUnixTime = currentPostUnixTime;
629 if (_this.hasNewFeeds) {
630 if (
631 "function" ===
632 typeof _this.getArgs().notification.setLastPostUnixTime
633 ) {
634 _this
635 .getArgs()
636 .notification.setLastPostUnixTime(currentPostUnixTime, key);
637 } else {
638 WhatsNewRSSCacheUtils.setLastPostUnixTime(
639 currentPostUnixTime,
640 key
641 );
642 }
643 }
644 }
645 })
646 .catch(console.error);
647 };
648 /**
649 * Open flyout on trigger button click.
650 * Flyout has three states: `closed | open | ready`
651 */
652 triggerButton.addEventListener("click", function (e) {
653 e.preventDefault();
654 _this.getArgs().triggerButton.onClick(_this);
655 _this.RSS_View_Instance.setIsLoading(true);
656 flyout.classList.remove("closed");
657 flyout.classList.add("open");
658 document.body.classList.add("whats-new-rss-is-active");
659 _this.getArgs().flyout.onOpen(_this);
660 if (!_this.isMultiFeedRSS()) {
661 injectContents(null);
662 return;
663 }
664 var navBtns = multiFeedNav.querySelectorAll("button");
665 navBtns.forEach(function (navBtn) {
666 _this.RSS_View_Instance.setMultiFeedTabNotificationCount(
667 navBtn.dataset.feedKey,
668 _this.multiNotificationCount[navBtn.dataset.feedKey]
669 );
670 navBtn.addEventListener("click", function (e) {
671 e.preventDefault();
672 var currentFeedKey = navBtn.dataset.feedKey;
673 _this.multiNotificationCount[currentFeedKey] = 0;
674 _this.RSS_Fetch_Instance.fetchData()
675 .then(function (res) {
676 var currentPostUnixTime = res[currentFeedKey][0].date;
677 _this.multiLastPostUnixTime[currentFeedKey] = currentPostUnixTime;
678 if (true === _this.multiHasNewFeeds[currentFeedKey]) {
679 if (
680 "function" ===
681 typeof _this.getArgs().notification.setLastPostUnixTime
682 ) {
683 _this
684 .getArgs()
685 .notification.setLastPostUnixTime(
686 currentPostUnixTime,
687 currentFeedKey
688 );
689 } else {
690 WhatsNewRSSCacheUtils.setLastPostUnixTime(
691 currentPostUnixTime,
692 currentFeedKey
693 );
694 }
695 }
696 _this.multiHasNewFeeds[currentFeedKey] = false;
697 })
698 .catch(console.error);
699 navBtns.forEach(function (navBtn) {
700 navBtn.classList.remove("selected");
701 var feedKey = navBtn.dataset.feedKey;
702 var innerContentClassName = ".inner-content-item-feed-key-".concat(
703 feedKey
704 );
705 document
706 .querySelectorAll(innerContentClassName)
707 .forEach(function (item) {
708 if (currentFeedKey !== feedKey) {
709 item.classList.add("hidden");
710 } else {
711 item.classList.remove("hidden");
712 }
713 });
714 });
715 navBtn.classList.add("selected");
716 injectContents(currentFeedKey);
717 });
718 });
719 navBtns[0].click();
720 });
721 /**
722 * Handle events for the closing of the flyout.
723 */
724 var handleFlyoutClose = function () {
725 flyout.classList.add("closed");
726 flyout.classList.remove("open");
727 flyout.classList.remove("ready");
728 document.body.classList.remove("whats-new-rss-is-active");
729 if (_this.isMultiFeedRSS()) {
730 _this.RSS_View_Instance.setNotification(
731 Object.values(_this.multiNotificationCount).filter(Boolean).length
732 );
733 } else {
734 _this.hasNewFeeds = false;
735 _this.RSS_View_Instance.setNotification(false);
736 }
737 flyoutInner.innerHTML = "";
738 _this.getArgs().flyout.onClose(_this);
739 /**
740 * Change focus back to trigger button after flyout close.
741 */
742 triggerButton.focus();
743 };
744 if (this.getArgs().flyout.closeOnEsc) {
745 document.addEventListener("keydown", function (e) {
746 if ("Escape" !== e.key) return;
747 if (!flyout.classList.contains("open")) return;
748 handleFlyoutClose();
749 });
750 }
751 if (this.getArgs().flyout.closeOnOverlayClick) {
752 flyout
753 .querySelector(".whats-new-rss-flyout-overlay")
754 .addEventListener("click", handleFlyoutClose);
755 }
756 flyoutCloseBtn.addEventListener("click", handleFlyoutClose);
757 };
758 return WhatsNewRSS;
759 })();
760 var WhatsNewRSSCacheUtils = /** @class */ (function () {
761 function WhatsNewRSSCacheUtils() {}
762 WhatsNewRSSCacheUtils.setInstanceID = function (instanceID) {
763 if (!this.instanceID) {
764 this.instanceID = instanceID;
765 }
766 };
767 WhatsNewRSSCacheUtils.prefixer = function (key, prefixKey) {
768 if (prefixKey === void 0) {
769 prefixKey = "";
770 }
771 if (!this.instanceID) {
772 throw new Error("Instance ID not set.");
773 }
774 return !!prefixKey
775 ? ""
776 .concat(this.keys[key], "-")
777 .concat(this.instanceID, "-")
778 .concat(prefixKey)
779 : "".concat(this.keys[key], "-").concat(this.instanceID);
780 };
781 WhatsNewRSSCacheUtils._setDataExpiry = function (prefixKey) {
782 if (prefixKey === void 0) {
783 prefixKey = "";
784 }
785 var expiryInSeconds = 86400; // Defaults to 24 hours.
786 var now = new Date();
787 var expiry = now.getTime() + expiryInSeconds * 1000;
788 sessionStorage.setItem(
789 this.prefixer("SESSION_DATA_EXPIRY", prefixKey),
790 JSON.stringify(expiry)
791 );
792 };
793 WhatsNewRSSCacheUtils._isDataExpired = function (prefixKey) {
794 if (prefixKey === void 0) {
795 prefixKey = "";
796 }
797 var key = this.prefixer("SESSION_DATA_EXPIRY", prefixKey);
798 var value = window.sessionStorage.getItem(key);
799 if (!value) {
800 return true;
801 }
802 var expiry = JSON.parse(value);
803 var now = new Date();
804 if (now.getTime() > expiry) {
805 window.sessionStorage.removeItem(key);
806 return true;
807 }
808 return false;
809 };
810 WhatsNewRSSCacheUtils.setSessionData = function (data, prefixKey) {
811 if (prefixKey === void 0) {
812 prefixKey = "";
813 }
814 this._setDataExpiry(prefixKey);
815 return window.sessionStorage.setItem(
816 this.prefixer("SESSION", prefixKey),
817 data
818 );
819 };
820 WhatsNewRSSCacheUtils.getSessionData = function (prefixKey) {
821 if (prefixKey === void 0) {
822 prefixKey = "";
823 }
824 if (!this._isDataExpired(prefixKey)) {
825 return window.sessionStorage.getItem(this.prefixer("SESSION", prefixKey));
826 }
827 return "{}";
828 };
829 WhatsNewRSSCacheUtils.setLastPostUnixTime = function (unixTime, prefixKey) {
830 if (prefixKey === void 0) {
831 prefixKey = "";
832 }
833 return window.localStorage.setItem(
834 this.prefixer("LAST_LATEST_POST", prefixKey),
835 unixTime.toString()
836 );
837 };
838 WhatsNewRSSCacheUtils.getLastPostUnixTime = function (prefixKey) {
839 if (prefixKey === void 0) {
840 prefixKey = "";
841 }
842 return +window.localStorage.getItem(
843 this.prefixer("LAST_LATEST_POST", prefixKey)
844 );
845 };
846 WhatsNewRSSCacheUtils.keys = {
847 SESSION_DATA_EXPIRY: "whats-new-cache-expiry",
848 LAST_LATEST_POST: "whats-new-last-unixtime",
849 SESSION: "whats-new-cache",
850 };
851 return WhatsNewRSSCacheUtils;
852 })();
853 /**
854 * Class for handling the data fetching.
855 * It also handles the session caching of the fetched data internally.
856 */
857 var WhatsNewRSSFetch = /** @class */ (function () {
858 function WhatsNewRSSFetch(RSS) {
859 var _this = this;
860 this.data = {};
861 this.RSS = RSS;
862 this.RSS.getRSSFeedURLs().forEach(function (feed) {
863 var sessionCache = JSON.parse(
864 WhatsNewRSSCacheUtils.getSessionData(feed.key)
865 );
866 if (sessionCache && sessionCache.length) {
867 _this.data[feed.key] = sessionCache;
868 }
869 });
870 }
871 WhatsNewRSSFetch.prototype.fetchData = function () {
872 return __awaiter(this, void 0, void 0, function () {
873 var fetchPromises;
874 var _this = this;
875 return __generator(this, function (_a) {
876 switch (_a.label) {
877 case 0:
878 if (Object.keys(this.data).length) {
879 return [2 /*return*/, this.data];
880 }
881 fetchPromises = this.RSS.getRSSFeedURLs().map(function (feed) {
882 return __awaiter(_this, void 0, void 0, function () {
883 var res, data, parser, xmlDoc, items;
884 var _this = this;
885 return __generator(this, function (_a) {
886 switch (_a.label) {
887 case 0:
888 this.data[feed.key] = [];
889 return [4 /*yield*/, fetch(feed.url)];
890 case 1:
891 res = _a.sent();
892 return [4 /*yield*/, res.text()];
893 case 2:
894 data = _a.sent();
895 /**
896 * There was an issue with the xml content parse
897 * And during parse we were getting "<parsererror>" because of the 'raquo' entity.
898 */
899 data = data.replace(/&raquo;/g, "&amp;raquo;");
900 parser = new DOMParser();
901 xmlDoc = parser.parseFromString(data, "text/xml");
902 items = xmlDoc.querySelectorAll("item");
903 items.forEach(function (item) {
904 var _a;
905 var title = item.querySelector("title").textContent;
906 var link = item.querySelector("link").textContent;
907 var contentEncoded = item.querySelector(
908 "content\\:encoded, encoded"
909 );
910 var content = contentEncoded
911 ? contentEncoded.textContent
912 : "";
913 var rssDate = item.querySelector("pubDate").innerHTML;
914 _this.data[feed.key].push({
915 title: title,
916 date: !!rssDate ? +new Date(rssDate) : null,
917 postLink: link,
918 description: content
919 .replace(
920 /<a\b((?:(?!target=)[^>])*)>/g,
921 '<a$1 target="_blank">'
922 )
923 .replace(/<p>\s*<\/p>/g, ""),
924 children: JSON.parse(
925 ((_a = item.querySelector("children")) === null ||
926 _a === void 0
927 ? void 0
928 : _a.innerHTML) || "{}"
929 ),
930 });
931 });
932 WhatsNewRSSCacheUtils.setSessionData(
933 JSON.stringify(this.data[feed.key]),
934 feed.key
935 );
936 return [2 /*return*/];
937 }
938 });
939 });
940 });
941 return [4 /*yield*/, Promise.all(fetchPromises)];
942 case 1:
943 _a.sent();
944 return [2 /*return*/, this.data];
945 }
946 });
947 });
948 };
949 return WhatsNewRSSFetch;
950 })();
951 /**
952 * The class for handling library trigger button and flyout elements.
953 * It also provides some necessary methods that can be used during development.
954 */
955 var WhatsNewRSSView = /** @class */ (function () {
956 function WhatsNewRSSView(RSS) {
957 this.RSS = RSS;
958 this.createTriggerButton();
959 this.createFlyOut();
960 }
961 WhatsNewRSSView.prototype.getTriggerButtonID = function () {
962 return "whats-new-rss-btn-".concat(this.RSS.getID());
963 };
964 WhatsNewRSSView.prototype.getFlyoutID = function () {
965 return "whats-new-rss-flyout-".concat(this.RSS.getID());
966 };
967 WhatsNewRSSView.prototype.getFlyoutCloseBtnID = function () {
968 return "whats-new-rss-flyout-close-".concat(this.RSS.getID());
969 };
970 WhatsNewRSSView.prototype.getFlyoutMultiFeedNavID = function () {
971 return "whats-new-rss-flyout-multi-feed-nav-".concat(this.RSS.getID());
972 };
973 WhatsNewRSSView.prototype.setIsLoading = function (isLoading) {
974 if (isLoading === void 0) {
975 isLoading = false;
976 }
977 var flyoutWrapper = document.getElementById(this.getFlyoutID());
978 if (isLoading) {
979 flyoutWrapper.classList.add("is-loading");
980 } else {
981 flyoutWrapper.classList.remove("is-loading");
982 }
983 };
984 WhatsNewRSSView.prototype.setNotification = function (notificationsCount) {
985 var notificationBadge = document.querySelector(
986 "#".concat(
987 this.getTriggerButtonID(),
988 " .whats-new-rss-notification-badge"
989 )
990 );
991 if (!!notificationsCount) {
992 if (this.RSS.isMultiFeedRSS()) {
993 notificationBadge.innerHTML = "";
994 notificationBadge.classList.add("is-multi-feed");
995 } else {
996 notificationBadge.innerHTML =
997 notificationsCount > 9 ? "9+" : notificationsCount.toString();
998 }
999 notificationBadge.classList.remove("hide");
1000 } else {
1001 notificationBadge.classList.add("hide");
1002 }
1003 };
1004 WhatsNewRSSView.prototype.createTriggerButton = function () {
1005 var button = "";
1006 var label = this.RSS.getArgs().triggerButton.label;
1007 if (!!label) {
1008 button = "\n\t\t\t"
1009 .concat(
1010 this.RSS.getArgs().triggerButton.beforeBtn,
1011 '\n\t\t\t<a class="whats-new-rss-trigger-button has-label" id="'
1012 )
1013 .concat(
1014 this.getTriggerButtonID(),
1015 '">\n\t\t\t\t<div class="icon-badge">\n\t\t\t\t\t'
1016 )
1017 .concat(
1018 this.RSS.getArgs().triggerButton.icon,
1019 '\n\t\t\t\t\t<div class="whats-new-rss-notification-badge hide">0</div>\n\t\t\t\t</div>\n\t\t\t\t'
1020 )
1021 .concat(label, "\n\t\t\t</a>\n\t\t\t")
1022 .concat(this.RSS.getArgs().triggerButton.afterBtn, "\n\t\t\t");
1023 } else {
1024 button = "\n\t\t\t"
1025 .concat(
1026 this.RSS.getArgs().triggerButton.beforeBtn,
1027 '\n\t\t\t<a class="whats-new-rss-trigger-button" id="'
1028 )
1029 .concat(this.getTriggerButtonID(), '">\n\t\t\t\t')
1030 .concat(
1031 this.RSS.getArgs().triggerButton.icon,
1032 '\n\t\t\t\t<div class="whats-new-rss-notification-badge hide">0</div>\n\t\t\t</a>\n\t\t\t'
1033 )
1034 .concat(this.RSS.getArgs().triggerButton.afterBtn, "\n\t\t\t");
1035 }
1036 this.RSS.getElement().innerHTML += button;
1037 };
1038 WhatsNewRSSView.prototype.createFlyOut = function () {
1039 var wrapperClasses = ["whats-new-rss-flyout", "closed"];
1040 if (this.RSS.getArgs().flyout.className) {
1041 wrapperClasses.push(this.RSS.getArgs().flyout.className);
1042 }
1043 var multiFeedNav = [];
1044 if (this.RSS.isMultiFeedRSS()) {
1045 multiFeedNav.push(
1046 '<nav id="'.concat(
1047 this.getFlyoutMultiFeedNavID(),
1048 '" class="whats-new-rss-multi-feed-nav">'
1049 )
1050 );
1051 this.RSS.getRSSFeedURLs().forEach(function (feed) {
1052 multiFeedNav.push(
1053 '<button type="button" data-feed-key="'
1054 .concat(feed.key, '">\n\t\t\t\t\t\t')
1055 .concat(
1056 feed.label,
1057 '\n\t\t\t\t\t\t<div class="new-notification-count"></div>\n\t\t\t\t\t</button>\n\t\t\t\t\t'
1058 )
1059 );
1060 });
1061 multiFeedNav.push("</nav>");
1062 }
1063 var flyoutWrapper = document.createElement("div");
1064 flyoutWrapper.setAttribute("id", this.getFlyoutID());
1065 flyoutWrapper.setAttribute("class", wrapperClasses.join(" "));
1066 flyoutWrapper.setAttribute("role", "dialog");
1067 flyoutWrapper.innerHTML =
1068 '\n\t\t<div class="whats-new-rss-flyout-contents">\n\n\t\t\t<div class="whats-new-rss-flyout-inner-header">\n\n\t\t\t\t<div class="whats-new-rss-flyout-inner-header__title-icon-wrapper">\n\t\t\t\t\t<h3>'
1069 .concat(
1070 this.RSS.getArgs().flyout.title,
1071 '</h3>\n\n\t\t\t\t\t<span class="whats-new-rss-flyout-inner-header__loading-icon">\n\t\t\t\t\t'
1072 )
1073 .concat(
1074 this.RSS.getArgs().loaderIcon,
1075 '\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\n\t\t\t\t<button type="button" id="'
1076 )
1077 .concat(this.getFlyoutCloseBtnID(), '">')
1078 .concat(
1079 this.RSS.getArgs().flyout.closeBtnIcon,
1080 "</button>\n\t\t\t</div>\n\n\t\t\t"
1081 )
1082 .concat(
1083 multiFeedNav.join(""),
1084 '\n\n\t\t\t<div class="whats-new-rss-flyout-inner-content">\n\t\t\t\t<div class="skeleton-container">\n\t\t\t\t\t<div class="skeleton-row whats-new-rss-flyout-inner-content-item"></div>\n\t\t\t\t\t<div class="skeleton-row whats-new-rss-flyout-inner-content-item"></div>\n\t\t\t\t\t<div class="skeleton-row whats-new-rss-flyout-inner-content-item"></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t</div>\n\n\t\t<div class="whats-new-rss-flyout-overlay"></div>\n\t\t'
1085 );
1086 document.body.appendChild(flyoutWrapper);
1087 };
1088 WhatsNewRSSView.prototype.setMultiFeedTabNotificationCount = function (
1089 key,
1090 notificationCount
1091 ) {
1092 if (notificationCount === void 0) {
1093 notificationCount = 0;
1094 }
1095 var tabBtn = document.querySelector(
1096 "#"
1097 .concat(this.getFlyoutMultiFeedNavID(), ' button[data-feed-key="')
1098 .concat(key, '"]')
1099 );
1100 if (!tabBtn) {
1101 return;
1102 }
1103 var el = tabBtn.querySelector(".new-notification-count");
1104 if (notificationCount) {
1105 var _count = notificationCount > 9 ? "9+" : notificationCount;
1106 el.innerHTML = _count.toString();
1107 } else {
1108 el.innerHTML = "";
1109 }
1110 };
1111 WhatsNewRSSView.prototype.innerContentWrapper = function (
1112 content,
1113 isNewPost,
1114 additionalClasses
1115 ) {
1116 if (isNewPost === void 0) {
1117 isNewPost = false;
1118 }
1119 if (additionalClasses === void 0) {
1120 additionalClasses = "";
1121 }
1122 var classes = ["whats-new-rss-flyout-inner-content-item"];
1123 if (isNewPost) {
1124 classes.push("rss-new-post");
1125 }
1126 if (!!additionalClasses) {
1127 classes.push(additionalClasses);
1128 }
1129 return '\n\t\t<div class="'
1130 .concat(classes.join(" "), '">\n\t\t\t')
1131 .concat(
1132 isNewPost ? '<small class="new-post-badge">New ✨</small>' : "",
1133 "\n\t\t\t"
1134 )
1135 .concat(content, "\n\t\t</div>\n\t\t");
1136 };
1137 WhatsNewRSSView.prototype.createExcerpt = function (
1138 content,
1139 readMoreLink,
1140 options
1141 ) {
1142 var wordLimit = options.wordLimit,
1143 moreSymbol = options.moreSymbol,
1144 readMore = options.readMore;
1145 if (!wordLimit) {
1146 return content;
1147 }
1148 var plainText = content.replace(/<[^>]*>/g, "");
1149 var words = plainText.split(/\s+/);
1150 var rawExcerpt = words.slice(0, wordLimit).join(" ");
1151 if (moreSymbol) {
1152 rawExcerpt += moreSymbol;
1153 }
1154 if (wordLimit > words.length) {
1155 return content;
1156 }
1157 if (
1158 !!readMoreLink &&
1159 !!(readMore === null || readMore === void 0 ? void 0 : readMore.label)
1160 ) {
1161 return "<p>"
1162 .concat(rawExcerpt, ' <a href="')
1163 .concat(readMoreLink, '" target="_blank" class="')
1164 .concat(readMore.className, '">')
1165 .concat(readMore.label, "</a></p>");
1166 }
1167 return "<p>".concat(rawExcerpt, "</p>");
1168 };
1169 WhatsNewRSSView.prototype.listChildrenPosts = function (children) {
1170 var _this = this;
1171 var _children = Object.values(children);
1172 if (!_children.length) return "";
1173 var details = document.createElement("details");
1174 var summary = document.createElement("summary");
1175 var itemsWrapper = document.createElement("div");
1176 _children.forEach(function (child) {
1177 var postContentDoc = new DOMParser().parseFromString(
1178 child.post_content,
1179 "text/html"
1180 );
1181 var itemDiv = document.createElement("div");
1182 itemDiv.classList.add("sub-version-item");
1183 itemDiv.innerHTML =
1184 '\n\t\t\t\t<div class="sub-version-header">\n\t\t\t\t\t<h4 class="sub-version-title">'
1185 .concat(
1186 child.post_title,
1187 '</h4>\n\t\t\t\t\t<span class="sub-version-date">'
1188 )
1189 .concat(
1190 _this.formatDate(new Date(child.post_date)),
1191 '</span>\n\t\t\t\t</div>\n\t\t\t\t<div class="sub-version-content">'
1192 )
1193 .concat(postContentDoc.documentElement.textContent, "</div>\n\t\t\t");
1194 itemsWrapper.appendChild(itemDiv);
1195 });
1196 summary.innerHTML =
1197 '<p class="text-see-more">See More</p><p class="text-see-less">See Less</p>';
1198 details.appendChild(summary);
1199 details.appendChild(itemsWrapper);
1200 itemsWrapper.classList.add("sub-version-items-wrapper");
1201 details.classList.add("whats-new-rss-sub-version-details");
1202 return details.outerHTML;
1203 };
1204 WhatsNewRSSView.prototype.formatDate = function (date) {
1205 if ("function" === typeof this.RSS.getArgs().flyout.formatDate) {
1206 return this.RSS.getArgs().flyout.formatDate(date);
1207 }
1208 var currentDate = new Date();
1209 var timestamp = date.getTime();
1210 var currentTimestamp = currentDate.getTime();
1211 var difference = currentTimestamp - timestamp;
1212 // Define time intervals in milliseconds
1213 var minute = 60 * 1000;
1214 var hour = minute * 60;
1215 var day = hour * 24;
1216 var week = day * 7;
1217 var month = day * 30; // Rough estimate, assuming 30 days in a month
1218 if (difference < minute) {
1219 return "Just now";
1220 } else if (difference < hour) {
1221 var minutes = Math.floor(difference / minute);
1222 return ""
1223 .concat(minutes, " minute")
1224 .concat(minutes > 1 ? "s" : "", " ago");
1225 } else if (difference < day) {
1226 var hours = Math.floor(difference / hour);
1227 return "".concat(hours, " hour").concat(hours > 1 ? "s" : "", " ago");
1228 } else if (difference < week) {
1229 var days = Math.floor(difference / day);
1230 return "".concat(days, " day").concat(days > 1 ? "s" : "", " ago");
1231 } else if (difference < month) {
1232 var weeks = Math.floor(difference / week);
1233 return "".concat(weeks, " week").concat(weeks > 1 ? "s" : "", " ago");
1234 } else {
1235 // Handle months and years accordingly
1236 // This is a rough estimate and may not be accurate in all cases
1237 var months = Math.floor(difference / month);
1238 return "".concat(months, " month").concat(months > 1 ? "s" : "", " ago");
1239 }
1240 };
1241 return WhatsNewRSSView;
1242 })();
1243
1244 async function getCSS() {
1245 return `.whats-new-rss-is-active{overflow:hidden}.whats-new-rss-trigger-button{display:flex;align-items:center;position:relative;width:auto;padding:5px;cursor:pointer}.whats-new-rss-trigger-button.has-label{align-items:end;gap:10px}.whats-new-rss-trigger-button.has-label .icon-badge{position:relative;line-height:1}.whats-new-rss-trigger-button.has-label .icon-badge .whats-new-rss-notification-badge{top:-12px;right:-10px}.whats-new-rss-trigger-button .whats-new-rss-notification-badge{position:absolute;top:-8px;right:-5px;width:20px;font-size:10px;line-height:20px;text-align:center;border-radius:10px;color:#fff;background:red;transition:transform .2s ease-in-out}.whats-new-rss-trigger-button .whats-new-rss-notification-badge.is-multi-feed{top:-2px;right:-2px;font-size:0;width:10px;height:10px}.whats-new-rss-trigger-button .whats-new-rss-notification-badge.hide{display:none}.whats-new-rss-trigger-button:hover .whats-new-rss-notification-badge{transform:scale(1.2)}.whats-new-rss-flyout{position:fixed;top:0;right:0;bottom:0;width:100%;z-index:99999;transition:visibility .3s ease-in-out;font-family:Arial,Helvetica,sans-serif}.whats-new-rss-flyout .lightbox-trigger,.whats-new-rss-flyout.hidden{display:none}.whats-new-rss-flyout.is-loading .whats-new-rss-flyout-inner-header__loading-icon{display:block;margin:auto}.whats-new-rss-flyout.is-loading .whats-new-rss-flyout-inner-header__loading-icon svg{display:block;background:0 0;width:25px;height:25px}.whats-new-rss-flyout .whats-new-rss-flyout-contents{position:fixed;display:flex;right:0;width:30%;height:100%;flex-direction:column;background-color:#fff;transition:transform .3s ease-in-out;z-index:9999}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-header{display:flex;justify-content:space-between;align-items:center;padding:16px 20px 16px 24px;border-bottom:1px solid #ccc}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-header button{border:none;background:0 0;font-size:30px;cursor:pointer;color:#94a3b8;padding:0;margin:0;box-shadow:none}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-header .whats-new-rss-flyout-inner-header__title-icon-wrapper{display:flex;gap:10px}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-header .whats-new-rss-flyout-inner-header__title-icon-wrapper h3{margin:0;padding:0;color:#0f172a;font-weight:600;font-size:16px;line-height:24px}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-multi-feed-nav{display:flex;padding:0 30px;border-bottom:1px solid #ccc;gap:2em;overflow:auto;white-space:nowrap}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-multi-feed-nav button{position:relative;background:0 0;color:inherit;padding:15px 0;border-bottom:2px solid transparent}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-multi-feed-nav button:focus,.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-multi-feed-nav button:hover{border-color:inherit}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-multi-feed-nav button.selected{border-color:#5d5d5d}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-multi-feed-nav button .new-notification-count{position:absolute;top:0;right:-10px;width:20px;font-size:10px;line-height:20px;text-align:center;border-radius:10px;color:#fff;background:red}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-content{flex:1;overflow-y:auto}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-content .skeleton-container{margin:30px}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-content .whats-new-rss-flyout-inner-content-item{border-bottom:1px solid #d8dfe9;padding:30px 24px;color:#475569;font-weight:400;font-size:14px;line-height:20px;display:flex;flex-direction:column;gap:13px}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-content .whats-new-rss-flyout-inner-content-item>*{margin:0}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-content .whats-new-rss-flyout-inner-content-item.skeleton-row{height:25vh;margin:40px 0;background:linear-gradient(90deg,#eee 25%,#ddd 50%,#eee 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-content .whats-new-rss-flyout-inner-content-item.rss-new-post{position:relative}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-content .whats-new-rss-flyout-inner-content-item.rss-new-post .new-post-badge{background:#ff3d3d;border-radius:5px;position:absolute;right:45px;padding:0 5px;color:#fff}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-content .whats-new-rss-flyout-inner-content-item .rss-content-header{display:flex;flex-direction:column;gap:15px;padding:0 0 8px 0}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-content .whats-new-rss-flyout-inner-content-item .rss-content-header p{color:#94a3b8;margin:0;padding:0;font-weight:600;font-size:14px;line-height:16px}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-content .whats-new-rss-flyout-inner-content-item .rss-content-header h2{margin:0;color:#0f172a;font-weight:700;line-height:28px;font-size:20px}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-content .whats-new-rss-flyout-inner-content-item h2{font-weight:700;font-size:18px;line-height:24px}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-content .whats-new-rss-flyout-inner-content-item h3{font-weight:700;font-size:16px;line-height:22px;margin-top:12px}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-content .whats-new-rss-flyout-inner-content-item h4{font-weight:700;font-size:15px;line-height:20px;margin-top:12px}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-content .whats-new-rss-flyout-inner-content-item h5{font-weight:700;font-size:14px;line-height:18px}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-content .whats-new-rss-flyout-inner-content-item h6{font-weight:700;font-size:13px;line-height:16px}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-content .whats-new-rss-flyout-inner-content-item p{padding:0;font-size:14px}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-content .whats-new-rss-flyout-inner-content-item p:last-child{margin-bottom:0;padding-bottom:0}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-content .whats-new-rss-flyout-inner-content-item a{color:#1170ff;text-decoration:none}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-content .whats-new-rss-flyout-inner-content-item figure{margin:10px 0}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-content .whats-new-rss-flyout-inner-content-item figure.wp-block-embed.is-type-video{position:relative;width:100%;height:0;padding-bottom:56.25%}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-content .whats-new-rss-flyout-inner-content-item figure iframe{position:absolute;top:0;left:0;width:100%;height:100%;border:0}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-content .whats-new-rss-flyout-inner-content-item img{box-sizing:border-box;height:auto;max-width:100%;vertical-align:bottom}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-content .whats-new-rss-flyout-inner-content-item video{vertical-align:middle;width:100%}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-content .whats-new-rss-flyout-inner-content-item strong{font-weight:600}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-content .whats-new-rss-flyout-inner-content-item ol,.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-content .whats-new-rss-flyout-inner-content-item ul{padding-inline-start:20px}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-content .whats-new-rss-flyout-inner-content-item ol li,.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-content .whats-new-rss-flyout-inner-content-item ul li{margin-bottom:5px}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-content .whats-new-rss-flyout-inner-content-item ul{list-style-type:disc}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-flyout-inner-content .whats-new-rss-flyout-inner-content-item ol{list-style-type:decimal}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-sub-version-details{line-height:20px;font-size:.9em;margin:10px 0;background:#f9fafb}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-sub-version-details summary{display:flex;justify-content:space-between;cursor:pointer;padding:20px 15px;height:1em;line-height:20px;font-weight:800}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-sub-version-details summary::after{content:"⌃";font-size:20px;transform:rotateX(180deg);font-weight:800}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-sub-version-details summary .text-see-more{display:block}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-sub-version-details summary .text-see-less{display:none}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-sub-version-details[open] summary{border-bottom:1px solid #e2e8f0}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-sub-version-details[open] summary::after{transform:rotateX(45deg)}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-sub-version-details[open] summary .text-see-more{display:none}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-sub-version-details[open] summary .text-see-less{display:block}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-sub-version-details .sub-version-item{position:relative;padding:1em;border-bottom:1px solid #e2e8f0}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-sub-version-details .sub-version-item .sub-version-header{display:flex;justify-content:space-between}.whats-new-rss-flyout .whats-new-rss-flyout-contents .whats-new-rss-sub-version-details .sub-version-item .sub-version-content{margin-top:1em}.whats-new-rss-flyout .whats-new-rss-flyout-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:rgba(0,0,0,.5);transition:all .3s ease-in-out}.whats-new-rss-flyout.closed{visibility:hidden}.whats-new-rss-flyout.closed .whats-new-rss-flyout-overlay{opacity:0;visibility:hidden}.whats-new-rss-flyout.closed .whats-new-rss-flyout-contents{transform:translateX(100%)}.whats-new-rss-flyout .whats-new-rss-flyout-inner-header__loading-icon{display:none}@keyframes shimmer{0%{background-position:-200% 0}100%{background-position:200% 0}}@media screen and (max-width:1024px){.whats-new-rss-flyout .whats-new-rss-flyout-contents{width:40%}}@media screen and (max-width:768px){.whats-new-rss-flyout .whats-new-rss-flyout-contents{width:85%}}`;
1246 }
1247
1248 async function addStyleIfNotExists() {
1249 const styleId = "whats-new-rss-styles";
1250 if (!document.getElementById(styleId)) {
1251 const style = document.createElement("style");
1252 style.id = styleId;
1253 style.innerHTML = await getCSS();
1254 document.head.appendChild(style);
1255 }
1256 }
1257
1258 function createWhatsNewRSSInstance(args) {
1259 return new WhatsNewRSS(args);
1260 }
1261
1262 function useWhatsNewRSS({ selector, ...rest }) {
1263 const instanceRef = useRef(null);
1264
1265 useEffect(() => {
1266 addStyleIfNotExists();
1267
1268 if (!instanceRef.current) {
1269 instanceRef.current = createWhatsNewRSSInstance({ selector, ...rest });
1270 }
1271
1272 // Cleanup function
1273 return () => {
1274 if (
1275 instanceRef.current &&
1276 typeof instanceRef.current.destroy === "function"
1277 ) {
1278 instanceRef.current.destroy();
1279 }
1280 };
1281 }, [selector, ...Object.values(rest)]); // Adjust dependencies as needed
1282
1283 return instanceRef.current;
1284 }
1285
1286 export default useWhatsNewRSS;
1287