@financial-times/cp-content-pipeline-ui 4.1.3 → 4.2.0-beta.0
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/.storybook/main.js +11 -0
- package/lib/components/LiveBlogBody/index.d.ts +1 -0
- package/lib/components/LiveBlogBody/index.js +10 -35
- package/lib/components/LiveBlogBody/index.js.map +1 -1
- package/lib/components/LiveBlogPost/ShareButtons.d.ts +7 -0
- package/lib/components/LiveBlogPost/ShareButtons.js +45 -0
- package/lib/components/LiveBlogPost/ShareButtons.js.map +1 -0
- package/lib/components/LiveBlogPost/Timestamp.d.ts +6 -0
- package/lib/components/LiveBlogPost/Timestamp.js +31 -0
- package/lib/components/LiveBlogPost/Timestamp.js.map +1 -0
- package/lib/components/LiveBlogPost/index.d.ts +30 -0
- package/lib/components/LiveBlogPost/index.js +68 -0
- package/lib/components/LiveBlogPost/index.js.map +1 -0
- package/lib/components/LiveBlogPost/svgIcons.d.ts +4 -0
- package/lib/components/LiveBlogPost/svgIcons.js +29 -0
- package/lib/components/LiveBlogPost/svgIcons.js.map +1 -0
- package/lib/components/LiveBlogWrapper/dispatchEvent.d.ts +2 -0
- package/lib/components/LiveBlogWrapper/dispatchEvent.js +39 -0
- package/lib/components/LiveBlogWrapper/dispatchEvent.js.map +1 -0
- package/lib/components/LiveBlogWrapper/index.d.ts +3 -0
- package/lib/components/LiveBlogWrapper/index.js +142 -0
- package/lib/components/LiveBlogWrapper/index.js.map +1 -0
- package/lib/components/LiveBlogWrapper/normalisePost.d.ts +2 -0
- package/lib/components/LiveBlogWrapper/normalisePost.js +14 -0
- package/lib/components/LiveBlogWrapper/normalisePost.js.map +1 -0
- package/lib/components/LiveBlogWrapper/post-tracker.d.ts +138 -0
- package/lib/components/LiveBlogWrapper/post-tracker.js +351 -0
- package/lib/components/LiveBlogWrapper/post-tracker.js.map +1 -0
- package/lib/components/LiveBlogWrapper/test/dispatchEvent.spec.d.ts +1 -0
- package/lib/components/LiveBlogWrapper/test/dispatchEvent.spec.js +44 -0
- package/lib/components/LiveBlogWrapper/test/dispatchEvent.spec.js.map +1 -0
- package/lib/components/LiveBlogWrapper/test/index.spec.d.ts +1 -0
- package/lib/components/LiveBlogWrapper/test/index.spec.js +100 -0
- package/lib/components/LiveBlogWrapper/test/index.spec.js.map +1 -0
- package/lib/components/LiveBlogWrapper/test/normalisePost.spec.d.ts +1 -0
- package/lib/components/LiveBlogWrapper/test/normalisePost.spec.js +28 -0
- package/lib/components/LiveBlogWrapper/test/normalisePost.spec.js.map +1 -0
- package/lib/components/Scrollytelling/ScrollyImage.js +1 -1
- package/lib/components/Scrollytelling/ScrollyImage.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +3 -1
- package/lib/index.js.map +1 -1
- package/lib/stories/LiveBlogPost.stories.d.ts +16 -0
- package/lib/stories/LiveBlogPost.stories.js +42 -0
- package/lib/stories/LiveBlogPost.stories.js.map +1 -0
- package/package.json +10 -3
- package/src/components/LiveBlogBody/client/main.scss +2 -0
- package/src/components/LiveBlogBody/index.tsx +17 -15
- package/src/components/LiveBlogPost/ShareButtons.tsx +86 -0
- package/src/components/LiveBlogPost/Timestamp.tsx +49 -0
- package/src/components/LiveBlogPost/index.tsx +164 -0
- package/src/components/LiveBlogPost/svgIcons.tsx +30 -0
- package/src/components/LiveBlogWrapper/dispatchEvent.ts +39 -0
- package/src/components/LiveBlogWrapper/index.tsx +189 -0
- package/src/components/LiveBlogWrapper/normalisePost.ts +11 -0
- package/src/components/LiveBlogWrapper/post-tracker.ts +458 -0
- package/src/components/LiveBlogWrapper/test/dispatchEvent.spec.ts +45 -0
- package/src/components/LiveBlogWrapper/test/index.spec.tsx +127 -0
- package/src/components/LiveBlogWrapper/test/normalisePost.spec.ts +31 -0
- package/src/components/Scrollytelling/ScrollyImage.tsx +1 -1
- package/src/index.ts +1 -0
- package/src/stories/LiveBlogPost.stories.scss +361 -0
- package/src/stories/LiveBlogPost.stories.tsx +38 -0
- package/src/types/x-dash.d.ts +4 -1
- package/tsconfig.tsbuildinfo +1 -1
package/.storybook/main.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
/** @type { import('@storybook/react-webpack5').StorybookConfig } */
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const xEngine = require('@financial-times/x-engine/src/webpack')
|
|
2
4
|
const config = {
|
|
3
5
|
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
|
|
4
6
|
addons: [
|
|
@@ -22,5 +24,14 @@ const config = {
|
|
|
22
24
|
docs: {
|
|
23
25
|
autodocs: 'tag',
|
|
24
26
|
},
|
|
27
|
+
webpackFinal: async (config) => {
|
|
28
|
+
config.plugins.push(xEngine());
|
|
29
|
+
config.resolve.modules.push(path.resolve(__dirname,"../../../node_modules/"));
|
|
30
|
+
config.resolve.alias.react = path.resolve(__dirname,"../../../node_modules/react");
|
|
31
|
+
config.resolve.alias['react-dom'] = path.resolve(__dirname,"../../../node_modules/react-dom");
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
return config;
|
|
35
|
+
},
|
|
25
36
|
}
|
|
26
37
|
export default config
|
|
@@ -2,5 +2,6 @@ import React from 'react';
|
|
|
2
2
|
import type { BodyProps } from '../Body';
|
|
3
3
|
export type LiveBlogBodyProps = BodyProps & {
|
|
4
4
|
isPinnedPost?: boolean;
|
|
5
|
+
xInteractionSerialiser?: any;
|
|
5
6
|
};
|
|
6
7
|
export default function LiveBlogBody({ content, components, isPinnedPost, xInteractionSerialiser, showShareButtons, showBackToTop, postTrackerConfig, }: LiveBlogBodyProps): React.JSX.Element | null;
|
|
@@ -1,48 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
4
|
};
|
|
28
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
6
|
const react_1 = __importDefault(require("react"));
|
|
30
|
-
const
|
|
31
|
-
const
|
|
7
|
+
const RichText_1 = require("../RichText");
|
|
8
|
+
const LiveBlogWrapper_1 = require("../LiveBlogWrapper");
|
|
32
9
|
function LiveBlogBody({ content, components, isPinnedPost, xInteractionSerialiser, showShareButtons, showBackToTop = true, postTrackerConfig, }) {
|
|
33
10
|
if (content.__typename !== 'LiveBlogPackage')
|
|
34
11
|
return null;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
posts: (content.liveBlogPosts || []).filter((post) => post?.id !== content.pinnedPost?.id),
|
|
43
|
-
};
|
|
12
|
+
let id = 'live-blog-wrapper';
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
14
|
+
let posts = (content.liveBlogPosts || []).filter((post) => post?.id !== content.pinnedPost?.id);
|
|
15
|
+
if (isPinnedPost) {
|
|
16
|
+
id = 'pinned-post-live-blog-wrapper';
|
|
17
|
+
posts = [content.pinnedPost];
|
|
18
|
+
}
|
|
44
19
|
return (react_1.default.createElement(RichText_1.ComponentsContext.Provider, { value: components },
|
|
45
|
-
react_1.default.createElement(
|
|
20
|
+
react_1.default.createElement(LiveBlogWrapper_1.LiveBlogWrapper, { articleUrl: `https://www.ft.com/content/${content.id}`, id: id, posts: posts, serialiser: xInteractionSerialiser, showShareButtons: showShareButtons ?? true, backToTop: showBackToTop ? 'o-topper' : undefined, postTrackerConfig: postTrackerConfig })));
|
|
46
21
|
}
|
|
47
22
|
exports.default = LiveBlogBody;
|
|
48
23
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/LiveBlogBody/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/LiveBlogBody/index.tsx"],"names":[],"mappings":";;;;;AAAA,kDAAyB;AAEzB,0CAA+C;AAC/C,wDAAoD;AAUpD,SAAwB,YAAY,CAAC,EACnC,OAAO,EACP,UAAU,EACV,YAAY,EACZ,sBAAsB,EACtB,gBAAgB,EAChB,aAAa,GAAG,IAAI,EACpB,iBAAiB,GACC;IAClB,IAAI,OAAO,CAAC,UAAU,KAAK,iBAAiB;QAAE,OAAO,IAAI,CAAA;IAEzD,IAAI,EAAE,GAAG,mBAAmB,CAAA;IAC5B,8DAA8D;IAC9D,IAAI,KAAK,GAAe,CAAC,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,MAAM,CAC1D,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,KAAK,OAAO,CAAC,UAAU,EAAE,EAAE,CAC9C,CAAA;IAED,IAAI,YAAY,EAAE;QAChB,EAAE,GAAG,+BAA+B,CAAA;QACpC,KAAK,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;KAC7B;IAED,OAAO,CACL,8BAAC,4BAAiB,CAAC,QAAQ,IAAC,KAAK,EAAE,UAAU;QAC3C,8BAAC,iCAAe,IACd,UAAU,EAAE,8BAA8B,OAAO,CAAC,EAAE,EAAE,EACtD,EAAE,EAAE,EAAE,EACN,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,sBAAsB,EAClC,gBAAgB,EAAE,gBAAgB,IAAI,IAAI,EAC1C,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,EACjD,iBAAiB,EAAE,iBAAiB,GACpC,CACyB,CAC9B,CAAA;AACH,CAAC;AAnCD,+BAmCC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const react_1 = __importDefault(require("react"));
|
|
7
|
+
const svgIcons_1 = require("./svgIcons");
|
|
8
|
+
exports.default = ({ postId, articleUrl, title, }) => {
|
|
9
|
+
const shareUrl = articleUrl ? new URL(articleUrl) : null;
|
|
10
|
+
if (shareUrl) {
|
|
11
|
+
shareUrl.hash = `post-${postId}`;
|
|
12
|
+
}
|
|
13
|
+
const shareUrlStr = shareUrl?.toString() ?? '';
|
|
14
|
+
const twitterUrl = `https://twitter.com/intent/tweet?url=${encodeURIComponent(shareUrlStr)}&text=${encodeURIComponent(title)}&via=ft`;
|
|
15
|
+
const facebookUrl = `http://www.facebook.com/sharer.php?u=${encodeURIComponent(shareUrlStr)}&t=${encodeURIComponent(title)}`;
|
|
16
|
+
const linkedInUrl = `http://www.linkedin.com/shareArticle?mini=true&url=${encodeURIComponent(shareUrlStr)}&title=${encodeURIComponent(title)}&source=Financial+Times`;
|
|
17
|
+
return (react_1.default.createElement("div", null,
|
|
18
|
+
react_1.default.createElement("div", { "data-o-component": "o-share", "data-o-share-location": `live-blog-post-${postId}`, className: "o-share o-share--small" },
|
|
19
|
+
react_1.default.createElement("ul", { "data-toolbar": "share" },
|
|
20
|
+
react_1.default.createElement("li", { className: "o-share__action", "data-share": "twitter" },
|
|
21
|
+
react_1.default.createElement("a", { className: "o-share__icon o-share__icon--x", rel: "noopener", href: twitterUrl, "data-trackable": "twitter" },
|
|
22
|
+
react_1.default.createElement("div", { className: "o-share__icon__image" },
|
|
23
|
+
react_1.default.createElement(svgIcons_1.TwitterSVG, null)),
|
|
24
|
+
react_1.default.createElement("span", { className: "o-share__text" },
|
|
25
|
+
"Share $",
|
|
26
|
+
title,
|
|
27
|
+
" on X (opens in a new window)"))),
|
|
28
|
+
react_1.default.createElement("li", { className: "o-share__action", "data-share": "facebook" },
|
|
29
|
+
react_1.default.createElement("a", { className: "o-share__icon o-share__icon--facebook", rel: "noopener", href: facebookUrl, "data-trackable": "facebook" },
|
|
30
|
+
react_1.default.createElement("div", { className: "o-share__icon__image" },
|
|
31
|
+
react_1.default.createElement(svgIcons_1.FacebookSVG, null)),
|
|
32
|
+
react_1.default.createElement("span", { className: "o-share__text" },
|
|
33
|
+
"Share $",
|
|
34
|
+
title,
|
|
35
|
+
" on Facebook (opens in a new window)"))),
|
|
36
|
+
react_1.default.createElement("li", { className: "o-share__action", "data-share": "linkedin" },
|
|
37
|
+
react_1.default.createElement("a", { className: "o-share__icon o-share__icon--linkedin", rel: "noopener", href: linkedInUrl, "data-trackable": "linkedin" },
|
|
38
|
+
react_1.default.createElement("div", { className: "o-share__icon__image" },
|
|
39
|
+
react_1.default.createElement(svgIcons_1.LinkedInSVG, null)),
|
|
40
|
+
react_1.default.createElement("span", { className: "o-share__text" },
|
|
41
|
+
"Share $",
|
|
42
|
+
title,
|
|
43
|
+
" on LinkedIn (opens in a new window)")))))));
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=ShareButtons.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ShareButtons.js","sourceRoot":"","sources":["../../../src/components/LiveBlogPost/ShareButtons.tsx"],"names":[],"mappings":";;;;;AAAA,kDAAyB;AACzB,yCAAiE;AACjE,kBAAe,CAAC,EACd,MAAM,EACN,UAAU,EACV,KAAK,GAKN,EAAE,EAAE;IACH,MAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACxD,IAAI,QAAQ,EAAE;QACZ,QAAQ,CAAC,IAAI,GAAG,QAAQ,MAAM,EAAE,CAAA;KACjC;IACD,MAAM,WAAW,GAAW,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAA;IACtD,MAAM,UAAU,GAAG,wCAAwC,kBAAkB,CAC3E,WAAW,CACZ,SAAS,kBAAkB,CAAC,KAAK,CAAC,SAAS,CAAA;IAE5C,MAAM,WAAW,GAAG,wCAAwC,kBAAkB,CAC5E,WAAW,CACZ,MAAM,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAA;IAElC,MAAM,WAAW,GAAG,sDAAsD,kBAAkB,CAC1F,WAAW,CACZ,UAAU,kBAAkB,CAAC,KAAK,CAAC,yBAAyB,CAAA;IAE7D,OAAO,CACL;QACE,2DACmB,SAAS,2BACH,kBAAkB,MAAM,EAAE,EACjD,SAAS,EAAC,wBAAwB;YAElC,sDAAiB,OAAO;gBACtB,sCAAI,SAAS,EAAC,iBAAiB,gBAAY,SAAS;oBAClD,qCACE,SAAS,EAAC,gCAAgC,EAC1C,GAAG,EAAC,UAAU,EACd,IAAI,EAAE,UAAU,oBACD,SAAS;wBAExB,uCAAK,SAAS,EAAC,sBAAsB;4BACnC,8BAAC,qBAAU,OAAG,CACV;wBACN,wCAAM,SAAS,EAAC,eAAe;;4BACrB,KAAK;4DACR,CACL,CACD;gBACL,sCAAI,SAAS,EAAC,iBAAiB,gBAAY,UAAU;oBACnD,qCACE,SAAS,EAAC,uCAAuC,EACjD,GAAG,EAAC,UAAU,EACd,IAAI,EAAE,WAAW,oBACF,UAAU;wBAEzB,uCAAK,SAAS,EAAC,sBAAsB;4BACnC,8BAAC,sBAAW,OAAG,CACX;wBACN,wCAAM,SAAS,EAAC,eAAe;;4BACrB,KAAK;mEACR,CACL,CACD;gBACL,sCAAI,SAAS,EAAC,iBAAiB,gBAAY,UAAU;oBACnD,qCACE,SAAS,EAAC,uCAAuC,EACjD,GAAG,EAAC,UAAU,EACd,IAAI,EAAE,WAAW,oBACF,UAAU;wBAEzB,uCAAK,SAAS,EAAC,sBAAsB;4BACnC,8BAAC,sBAAW,OAAG,CACX;wBACN,wCAAM,SAAS,EAAC,eAAe;;4BACrB,KAAK;mEACR,CACL,CACD,CACF,CACD,CACF,CACP,CAAA;AACH,CAAC,CAAA"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const react_1 = __importDefault(require("react"));
|
|
7
|
+
exports.default = ({ publishedTimestamp }) => {
|
|
8
|
+
const now = new Date();
|
|
9
|
+
const oneDay = 24 * 60 * 60 * 1000;
|
|
10
|
+
const date = new Date(publishedTimestamp);
|
|
11
|
+
const formatted = date.toLocaleString();
|
|
12
|
+
let format;
|
|
13
|
+
let showExactTime;
|
|
14
|
+
if (now.getTime() - date.getTime() < oneDay) {
|
|
15
|
+
// display published date in 'xx minutes ago' format
|
|
16
|
+
// and render exact time next to it
|
|
17
|
+
format = 'time-ago-no-seconds';
|
|
18
|
+
showExactTime = true;
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
// don't display time string if the post is older than one day
|
|
22
|
+
// because it is already included in the formatted timestamp
|
|
23
|
+
format = 'MMM dd, HH:mm';
|
|
24
|
+
showExactTime = false;
|
|
25
|
+
}
|
|
26
|
+
return (react_1.default.createElement("span", { className: "x-live-blog-post__timestamp-container" },
|
|
27
|
+
react_1.default.createElement("time", { "data-o-component": "o-date", className: "o-date x-live-blog-post__timestamp", dateTime: publishedTimestamp, "data-o-date-format": format, itemProp: "datePublished" },
|
|
28
|
+
react_1.default.createElement("span", { "data-o-date-printer": true }, formatted),
|
|
29
|
+
showExactTime && (react_1.default.createElement("span", { className: "o-date x-live-blog-post__timestamp-exact-time", "data-o-date-printer": true, "data-o-date-format": "HH:mm", itemProp: "exactTime" })))));
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=Timestamp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Timestamp.js","sourceRoot":"","sources":["../../../src/components/LiveBlogPost/Timestamp.tsx"],"names":[],"mappings":";;;;;AAAA,kDAAyB;AAMzB,kBAAe,CAAC,EAAE,kBAAkB,EAAkB,EAAE,EAAE;IACxD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAA;IACtB,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;IAClC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,kBAAkB,CAAC,CAAA;IACzC,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,EAAE,CAAA;IAEvC,IAAI,MAAc,CAAA;IAClB,IAAI,aAAsB,CAAA;IAE1B,IAAI,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,MAAM,EAAE;QAC3C,oDAAoD;QACpD,mCAAmC;QACnC,MAAM,GAAG,qBAAqB,CAAA;QAC9B,aAAa,GAAG,IAAI,CAAA;KACrB;SAAM;QACL,8DAA8D;QAC9D,4DAA4D;QAC5D,MAAM,GAAG,eAAe,CAAA;QACxB,aAAa,GAAG,KAAK,CAAA;KACtB;IAED,OAAO,CACL,wCAAM,SAAS,EAAC,uCAAuC;QACrD,4DACmB,QAAQ,EACzB,SAAS,EAAC,oCAAoC,EAC9C,QAAQ,EAAE,kBAAkB,wBACR,MAAM,EAC1B,QAAQ,EAAC,eAAe;YAExB,uEAA2B,SAAS,CAAQ;YAC3C,aAAa,IAAI,CAChB,wCACE,SAAS,EAAC,+CAA+C,qDAEtC,OAAO,EAC1B,QAAQ,EAAC,WAAW,GACd,CACT,CACI,CACF,CACR,CAAA;AACH,CAAC,CAAA"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { RichTextProps } from '../RichText';
|
|
3
|
+
type indicators = {
|
|
4
|
+
isOpinion?: boolean;
|
|
5
|
+
};
|
|
6
|
+
export type LiveBlogPostProps = {
|
|
7
|
+
id: string;
|
|
8
|
+
postId: string;
|
|
9
|
+
title: string;
|
|
10
|
+
content: string;
|
|
11
|
+
bodyHTML: string;
|
|
12
|
+
body: any;
|
|
13
|
+
publishedTimestamp: string;
|
|
14
|
+
publishedDate: string;
|
|
15
|
+
isBreakingNews: boolean;
|
|
16
|
+
standout?: {
|
|
17
|
+
breakingNews?: boolean;
|
|
18
|
+
editorsChoice?: boolean;
|
|
19
|
+
exclusive?: boolean;
|
|
20
|
+
scoop?: boolean;
|
|
21
|
+
};
|
|
22
|
+
articleUrl: string;
|
|
23
|
+
showShareButtons: boolean;
|
|
24
|
+
byline: string | RichTextProps;
|
|
25
|
+
ad: unknown;
|
|
26
|
+
backToTop: string | undefined | ((arg: any) => any);
|
|
27
|
+
indicators?: indicators;
|
|
28
|
+
};
|
|
29
|
+
declare const LiveBlogPost: ({ id, postId, title, content, bodyHTML, body, publishedTimestamp, publishedDate, isBreakingNews, standout, articleUrl, showShareButtons, byline, ad, backToTop, indicators, }: LiveBlogPostProps) => React.JSX.Element | null;
|
|
30
|
+
export { LiveBlogPost };
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.LiveBlogPost = void 0;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
const ShareButtons_1 = __importDefault(require("./ShareButtons"));
|
|
9
|
+
const Timestamp_1 = __importDefault(require("./Timestamp"));
|
|
10
|
+
const RichText_1 = __importDefault(require("../RichText"));
|
|
11
|
+
const classnames_1 = __importDefault(require("classnames"));
|
|
12
|
+
const LiveBlogPost = ({ id, postId, // Remove once wordpress is no longer in use
|
|
13
|
+
title, content, // Remove once wordpress is no longer in use
|
|
14
|
+
bodyHTML, //ElasticSearch
|
|
15
|
+
body, // cp-content-pipeline
|
|
16
|
+
publishedTimestamp, // Remove once wordpress is no longer in use
|
|
17
|
+
publishedDate, isBreakingNews, // Remove once wordpress is no longer in use
|
|
18
|
+
standout = {}, articleUrl, showShareButtons = false, byline, ad, backToTop, indicators = {}, }) => {
|
|
19
|
+
const showBreakingNewsLabel = standout.breakingNews || isBreakingNews;
|
|
20
|
+
let postBody;
|
|
21
|
+
let postByline;
|
|
22
|
+
let backToTopElem;
|
|
23
|
+
if (body && 'structured' in body) {
|
|
24
|
+
// Content comes from cp-content-pipeline-api
|
|
25
|
+
postBody = (react_1.default.createElement("div", { className: "x-live-blog-post__body n-content-body article--body" },
|
|
26
|
+
react_1.default.createElement(RichText_1.default, { structuredContent: body.structured })));
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
// Content comes from next-es or wordpress
|
|
30
|
+
postBody = (react_1.default.createElement("div", { className: "x-live-blog-post__body n-content-body article--body", dangerouslySetInnerHTML: { __html: bodyHTML || content } }));
|
|
31
|
+
}
|
|
32
|
+
if (byline && typeof byline === 'object' && 'tree' in byline) {
|
|
33
|
+
postByline = (react_1.default.createElement("p", { className: "x-live-blog-post__byline" },
|
|
34
|
+
react_1.default.createElement(RichText_1.default, { structuredContent: byline })));
|
|
35
|
+
}
|
|
36
|
+
else if (typeof byline === 'string') {
|
|
37
|
+
postByline = react_1.default.createElement("p", { className: "x-live-blog-post__byline" }, byline);
|
|
38
|
+
}
|
|
39
|
+
if (typeof backToTop === 'string') {
|
|
40
|
+
backToTopElem = (react_1.default.createElement("a", { href: backToTop.includes('#') ? backToTop : `#${backToTop}`, className: "x-live-blog-post-controls__back-to-top-link" }, "Back to top"));
|
|
41
|
+
}
|
|
42
|
+
else if (typeof backToTop === 'function') {
|
|
43
|
+
backToTopElem = (react_1.default.createElement("button", { onClick: backToTop, className: "x-live-blog-post-controls__back-to-top-button" }, "Back to top"));
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
return (react_1.default.createElement("article", { className: (0, classnames_1.default)('x-live-blog-post', {
|
|
49
|
+
'x-live-blog-post--opinion': indicators.isOpinion,
|
|
50
|
+
}), "data-trackable": "live-post", id: `post-${id || postId}`, "data-x-component": "live-blog-post" },
|
|
51
|
+
react_1.default.createElement("div", { className: "x-live-blog-post__standout" },
|
|
52
|
+
indicators.isOpinion ? (react_1.default.createElement("span", { className: "icon icon-opinion icon--scale-3" })) : (''),
|
|
53
|
+
react_1.default.createElement("div", { className: "x-live-blog-post__right" },
|
|
54
|
+
react_1.default.createElement("div", { className: "x-live-blog-post__meta" },
|
|
55
|
+
indicators.isOpinion ? (react_1.default.createElement("span", { className: "x-live-blog-post__label--opinion" }, "Live Opinion")) : (''),
|
|
56
|
+
react_1.default.createElement("span", null,
|
|
57
|
+
react_1.default.createElement(Timestamp_1.default, { publishedTimestamp: publishedDate || publishedTimestamp }))),
|
|
58
|
+
react_1.default.createElement("div", null, postByline))),
|
|
59
|
+
showBreakingNewsLabel && (react_1.default.createElement("div", { className: "x-live-blog-post__breaking-news" }, "Breaking news")),
|
|
60
|
+
title && react_1.default.createElement("h2", { className: "x-live-blog-post__title" }, title),
|
|
61
|
+
postBody,
|
|
62
|
+
react_1.default.createElement("div", { className: "x-live-blog-post__controls" },
|
|
63
|
+
showShareButtons && (react_1.default.createElement(ShareButtons_1.default, { postId: id || postId, articleUrl: articleUrl, title: title })),
|
|
64
|
+
backToTopElem),
|
|
65
|
+
ad));
|
|
66
|
+
};
|
|
67
|
+
exports.LiveBlogPost = LiveBlogPost;
|
|
68
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/LiveBlogPost/index.tsx"],"names":[],"mappings":";;;;;;AAAA,kDAAyB;AACzB,kEAAyC;AACzC,4DAAmC;AACnC,2DAAqD;AACrD,4DAAmC;AAiCnC,MAAM,YAAY,GAAG,CAAC,EACpB,EAAE,EACF,MAAM,EAAE,4CAA4C;AACpD,KAAK,EACL,OAAO,EAAE,4CAA4C;AACrD,QAAQ,EAAE,eAAe;AACzB,IAAI,EAAE,sBAAsB;AAC5B,kBAAkB,EAAE,4CAA4C;AAChE,aAAa,EACb,cAAc,EAAE,4CAA4C;AAC5D,QAAQ,GAAG,EAAE,EACb,UAAU,EACV,gBAAgB,GAAG,KAAK,EACxB,MAAM,EACN,EAAE,EACF,SAAS,EACT,UAAU,GAAG,EAAE,GACG,EAAE,EAAE;IACtB,MAAM,qBAAqB,GAAG,QAAQ,CAAC,YAAY,IAAI,cAAc,CAAA;IAErE,IAAI,QAAQ,CAAA;IACZ,IAAI,UAAU,CAAA;IACd,IAAI,aAAa,CAAA;IAEjB,IAAI,IAAI,IAAI,YAAY,IAAI,IAAI,EAAE;QAChC,6CAA6C;QAC7C,QAAQ,GAAG,CACT,uCAAK,SAAS,EAAC,qDAAqD;YAClE,8BAAC,kBAAQ,IAAC,iBAAiB,EAAE,IAAI,CAAC,UAAU,GAAI,CAC5C,CACP,CAAA;KACF;SAAM;QACL,0CAA0C;QAC1C,QAAQ,GAAG,CACT,uCACE,SAAS,EAAC,qDAAqD,EAC/D,uBAAuB,EAAE,EAAE,MAAM,EAAE,QAAQ,IAAI,OAAO,EAAE,GACxD,CACH,CAAA;KACF;IAED,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,IAAI,MAAM,EAAE;QAC5D,UAAU,GAAG,CACX,qCAAG,SAAS,EAAC,0BAA0B;YACrC,8BAAC,kBAAQ,IAAC,iBAAiB,EAAE,MAAM,GAAI,CACrC,CACL,CAAA;KACF;SAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;QACrC,UAAU,GAAG,qCAAG,SAAS,EAAC,0BAA0B,IAAE,MAAM,CAAK,CAAA;KAClE;IAED,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE;QACjC,aAAa,GAAG,CACd,qCACE,IAAI,EAAE,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,SAAS,EAAE,EAC3D,SAAS,EAAC,6CAA6C,kBAGrD,CACL,CAAA;KACF;SAAM,IAAI,OAAO,SAAS,KAAK,UAAU,EAAE;QAC1C,aAAa,GAAG,CACd,0CACE,OAAO,EAAE,SAAS,EAClB,SAAS,EAAC,+CAA+C,kBAGlD,CACV,CAAA;KACF;SAAM;QACL,OAAO,IAAI,CAAA;KACZ;IAED,OAAO,CACL,2CACE,SAAS,EAAE,IAAA,oBAAU,EAAC,kBAAkB,EAAE;YACxC,2BAA2B,EAAE,UAAU,CAAC,SAAS;SAClD,CAAC,oBACa,WAAW,EAC1B,EAAE,EAAE,QAAQ,EAAE,IAAI,MAAM,EAAE,sBACT,gBAAgB;QAEjC,uCAAK,SAAS,EAAC,4BAA4B;YACxC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CACtB,wCAAM,SAAS,EAAC,iCAAiC,GAAQ,CAC1D,CAAC,CAAC,CAAC,CACF,EAAE,CACH;YACD,uCAAK,SAAS,EAAC,yBAAyB;gBACtC,uCAAK,SAAS,EAAC,wBAAwB;oBACpC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CACtB,wCAAM,SAAS,EAAC,kCAAkC,mBAE3C,CACR,CAAC,CAAC,CAAC,CACF,EAAE,CACH;oBACD;wBACE,8BAAC,mBAAS,IACR,kBAAkB,EAAE,aAAa,IAAI,kBAAkB,GACvD,CACG,CACH;gBACN,2CAAM,UAAU,CAAO,CACnB,CACF;QACL,qBAAqB,IAAI,CACxB,uCAAK,SAAS,EAAC,iCAAiC,oBAAoB,CACrE;QACA,KAAK,IAAI,sCAAI,SAAS,EAAC,yBAAyB,IAAE,KAAK,CAAM;QAC7D,QAAQ;QACT,uCAAK,SAAS,EAAC,4BAA4B;YACxC,gBAAgB,IAAI,CACnB,8BAAC,sBAAY,IACX,MAAM,EAAE,EAAE,IAAI,MAAM,EACpB,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,KAAK,GACZ,CACH;YACA,aAAa,CACV;QACL,EAAS,CACF,CACX,CAAA;AACH,CAAC,CAAA;AAEQ,oCAAY"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.LinkedInSVG = exports.FacebookSVG = exports.TwitterSVG = void 0;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
/*
|
|
9
|
+
TODO: CI-1975 given the below comment, once we are happy this migration works, we should replace this with o-share
|
|
10
|
+
|
|
11
|
+
These icons have been copied from Origami as their TSX components are currently incompatible with next-article.
|
|
12
|
+
Once this is resolved, these components should be replaced with o-share https://github.com/Financial-Times/origami/tree/main/components/o-share.
|
|
13
|
+
*/
|
|
14
|
+
function TwitterSVG() {
|
|
15
|
+
return (react_1.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 40 40" },
|
|
16
|
+
react_1.default.createElement("path", { d: "M21.647 18.469 28.932 10h-1.726l-6.326 7.353L15.827 10H10l7.64 11.12L10 30h1.726l6.68-7.765L23.744 30h5.827l-7.924-11.531Zm-2.365 2.748-.774-1.107-6.16-8.81H15l4.971 7.11.774 1.107 6.462 9.242h-2.652l-5.273-7.541Z" })));
|
|
17
|
+
}
|
|
18
|
+
exports.TwitterSVG = TwitterSVG;
|
|
19
|
+
function FacebookSVG() {
|
|
20
|
+
return (react_1.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 1024 1024" },
|
|
21
|
+
react_1.default.createElement("path", { d: "M643.9 342h-48.2c-37.8 0-45.1 18-45.1 44.3v58.1h90.1l-11.7 91h-78.4V769h-94V535.5H378v-91h78.6v-67.1c0-77.9 47.6-120.3 117.1-120.3 33.3 0 61.9 2.5 70.2 3.6V342z" })));
|
|
22
|
+
}
|
|
23
|
+
exports.FacebookSVG = FacebookSVG;
|
|
24
|
+
function LinkedInSVG() {
|
|
25
|
+
return (react_1.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 1024 1024" },
|
|
26
|
+
react_1.default.createElement("path", { d: "M264.4 426.2h106.2v341.4H264.4V426.2zm53.2-169.7c-34.1 0-61.6 27.6-61.6 61.5 0 34 27.5 61.5 61.6 61.5 33.9 0 61.5-27.6 61.5-61.5-.1-34-27.6-61.5-61.5-61.5zm323.1 161.2c-51.6 0-86.2 28.3-100.4 55.1h-1.5v-46.7H437.2v341.4h106V598.7c0-44.5 8.4-87.7 63.6-87.7 54.5 0 55.1 50.9 55.1 90.5v166H768V580.3c0-91.9-19.9-162.6-127.3-162.6z" })));
|
|
27
|
+
}
|
|
28
|
+
exports.LinkedInSVG = LinkedInSVG;
|
|
29
|
+
//# sourceMappingURL=svgIcons.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svgIcons.js","sourceRoot":"","sources":["../../../src/components/LiveBlogPost/svgIcons.tsx"],"names":[],"mappings":";;;;;;AAAA,kDAAyB;AACzB;;;;;GAKG;AACH,SAAgB,UAAU;IACxB,OAAO,CACL,uCAAK,KAAK,EAAC,4BAA4B,EAAC,OAAO,EAAC,WAAW;QACzD,wCAAM,CAAC,EAAC,uNAAuN,GAAG,CAC9N,CACP,CAAA;AACH,CAAC;AAND,gCAMC;AAED,SAAgB,WAAW;IACzB,OAAO,CACL,uCAAK,KAAK,EAAC,4BAA4B,EAAC,OAAO,EAAC,eAAe;QAC7D,wCAAM,CAAC,EAAC,kKAAkK,GAAG,CACzK,CACP,CAAA;AACH,CAAC;AAND,kCAMC;AAED,SAAgB,WAAW;IACzB,OAAO,CACL,uCAAK,KAAK,EAAC,4BAA4B,EAAC,OAAO,EAAC,eAAe;QAC7D,wCAAM,CAAC,EAAC,yUAAyU,GAAG,CAChV,CACP,CAAA;AACH,CAAC;AAND,kCAMC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.dispatchEvent = void 0;
|
|
4
|
+
/*
|
|
5
|
+
We dispatch live update events to notify the consuming app about added / updated posts.
|
|
6
|
+
|
|
7
|
+
Consuming app uses these events to execute tasks like initialising Origami components
|
|
8
|
+
on the updated elements.
|
|
9
|
+
|
|
10
|
+
We want the rendering of the updates in the DOM to finish before dispatching this event,
|
|
11
|
+
because the consumer needs to reference the updated DOM elements.
|
|
12
|
+
|
|
13
|
+
If we dispatch the event in the same event loop with DOM element updates, consumer app
|
|
14
|
+
will handle the event before the updates are complete.
|
|
15
|
+
|
|
16
|
+
window.setTimeout(fn, 0) will defer the execution of the inner function until the
|
|
17
|
+
current event loop completes, which is enough time for the DOM updates to finish.
|
|
18
|
+
|
|
19
|
+
More information can be found in MDN setTimeout documentation. Please refer to
|
|
20
|
+
"Late timeouts" heading in this page:
|
|
21
|
+
https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout#Late_timeouts
|
|
22
|
+
|
|
23
|
+
> ... the timeout can also fire later when the page (or the OS/browser itself) is busy
|
|
24
|
+
> with other tasks. One important case to note is that the function or code snippet
|
|
25
|
+
> cannot be executed until the thread that called setTimeout() has terminated.
|
|
26
|
+
> ...
|
|
27
|
+
> This is because even though setTimeout was called with a delay of zero, it's placed on
|
|
28
|
+
> a queue and scheduled to run at the next opportunity; not immediately.
|
|
29
|
+
*/
|
|
30
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
31
|
+
//TODO: CI-1975 reset any types to something better, requires quite a bit of digging
|
|
32
|
+
const dispatchEvent = (target, eventType, data) => {
|
|
33
|
+
if (typeof window === 'undefined') {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
window.setTimeout(() => target.dispatchEvent(new CustomEvent(eventType, { detail: data })), 0);
|
|
37
|
+
};
|
|
38
|
+
exports.dispatchEvent = dispatchEvent;
|
|
39
|
+
//# sourceMappingURL=dispatchEvent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatchEvent.js","sourceRoot":"","sources":["../../../src/components/LiveBlogWrapper/dispatchEvent.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;EAyBE;AACF,uDAAuD;AACvD,oFAAoF;AACpF,MAAM,aAAa,GAAG,CAAC,MAAW,EAAE,SAAc,EAAE,IAAS,EAAE,EAAE;IAC/D,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;QACjC,OAAM;KACP;IACD,MAAM,CAAC,UAAU,CACf,GAAG,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EACxE,CAAC,CACF,CAAA;AACH,CAAC,CAAA;AAEQ,sCAAa"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.PostTracker = exports.LiveBlogWrapper = void 0;
|
|
27
|
+
const react_1 = __importStar(require("react"));
|
|
28
|
+
const x_interaction_1 = require("@financial-times/x-interaction");
|
|
29
|
+
const normalisePost_1 = require("./normalisePost");
|
|
30
|
+
const dispatchEvent_1 = require("./dispatchEvent");
|
|
31
|
+
const post_tracker_1 = require("./post-tracker");
|
|
32
|
+
Object.defineProperty(exports, "PostTracker", { enumerable: true, get: function () { return post_tracker_1.PostTracker; } });
|
|
33
|
+
const LiveBlogPost_1 = require("../LiveBlogPost");
|
|
34
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
35
|
+
//TODO: CI-1975 remove "any" types
|
|
36
|
+
// this has been ported from x-dash, and a lot of what is expected into these arguments will take a lot of digging
|
|
37
|
+
// checks to see if there is already a post and if not inserts it. tracks with dispatchEvent
|
|
38
|
+
const withLiveBlogWrapperActions = (0, x_interaction_1.withActions)({
|
|
39
|
+
insertPost(newPost, wrapper) {
|
|
40
|
+
return (props) => {
|
|
41
|
+
const normalisedNewPost = (0, normalisePost_1.normalisePost)(newPost);
|
|
42
|
+
const newPostAlreadyExists = props.posts.find((post) => post.id === normalisedNewPost.id);
|
|
43
|
+
if (!newPostAlreadyExists) {
|
|
44
|
+
props.posts.unshift(normalisedNewPost);
|
|
45
|
+
(0, dispatchEvent_1.dispatchEvent)(wrapper, 'LiveBlogWrapper.INSERT_POST', {
|
|
46
|
+
post: normalisedNewPost,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
return props;
|
|
50
|
+
};
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
class BaseLiveBlogWrapper extends react_1.Component {
|
|
54
|
+
constructor(props) {
|
|
55
|
+
super(props);
|
|
56
|
+
}
|
|
57
|
+
componentDidUpdate(prevProps) {
|
|
58
|
+
if (this.props.posts && this.props.posts.length && !this.state.tracker) {
|
|
59
|
+
this.setUp();
|
|
60
|
+
}
|
|
61
|
+
if (this.state.tracker && prevProps.posts.length !== this.state.postCount) {
|
|
62
|
+
this.state.tracker.observeNewElements();
|
|
63
|
+
this.setState({ postCount: this.props.posts.length });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
componentWillUnmount() {
|
|
67
|
+
if (this.state.tracker) {
|
|
68
|
+
this.state.tracker.destroy();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
setUp() {
|
|
72
|
+
const { onEntersViewport, onRead, onError, usePostTracker } = this.props.postTrackerConfig || {};
|
|
73
|
+
if (!usePostTracker) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (typeof onEntersViewport !== 'function' ||
|
|
77
|
+
typeof onRead !== 'function' ||
|
|
78
|
+
typeof onError !== 'function') {
|
|
79
|
+
// eslint-disable-next-line no-console
|
|
80
|
+
console.error('onEntersViewport, onRead and onError callback functions are required to use Post tracker');
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const tracker = this.setUpPostTracking({ onEntersViewport, onRead, onError }, this.props.id);
|
|
84
|
+
this.setState({
|
|
85
|
+
tracker,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
*
|
|
90
|
+
* @param {Object} callbacks - Callbacks to be called by PostTracker class
|
|
91
|
+
* @param {Function} callbacks.onEntersViewport - function to be called when the criteria for `view` in Post tracker has been fulfiled
|
|
92
|
+
* @param {Function} callbacks.onRead - function to be called when the criteria for `read` in Post tracker has been fulfiled
|
|
93
|
+
* @param {Function} callbacks.onError - function to be called when PostTracker encounters an error
|
|
94
|
+
* @param {string} id
|
|
95
|
+
* @returns {PostTracker}
|
|
96
|
+
*/
|
|
97
|
+
setUpPostTracking(callbacks, id) {
|
|
98
|
+
/**
|
|
99
|
+
* @type {import('./post-tracker').PostTrackerConfig}
|
|
100
|
+
*/
|
|
101
|
+
const config = {
|
|
102
|
+
query: 'article[data-trackable="live-post"]',
|
|
103
|
+
minMillisecondsToReport: 5000,
|
|
104
|
+
returnVisibleElement: true,
|
|
105
|
+
observerUpdateEventString: 'LiveBlogWrapper.INSERT_POST',
|
|
106
|
+
liveBlogWrapperQuery: `div[data-live-blog-wrapper-id="${id}"]`,
|
|
107
|
+
liveBlogWrapper: this.props.liveBlogWrapperElementRef
|
|
108
|
+
? this.props.liveBlogWrapperElementRef.current
|
|
109
|
+
: undefined,
|
|
110
|
+
onEntersViewport: (event) => callbacks.onEntersViewport(event),
|
|
111
|
+
onRead: (event) => callbacks.onRead(event),
|
|
112
|
+
onError: (event) => callbacks.onError(event),
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* @type {PostTracker}
|
|
116
|
+
*/
|
|
117
|
+
return new post_tracker_1.PostTracker(config);
|
|
118
|
+
}
|
|
119
|
+
render() {
|
|
120
|
+
const { posts = [], ads = {}, articleUrl, showShareButtons, id, liveBlogWrapperElementRef, } = this.props;
|
|
121
|
+
//TODO: CI-1975 these types can move out when we have a posts type properly defined and shared
|
|
122
|
+
posts.sort((a, b) => {
|
|
123
|
+
const timestampA = a.publishedDate || a.publishedTimestamp;
|
|
124
|
+
const timestampB = b.publishedDate || b.publishedTimestamp;
|
|
125
|
+
// Newer posts on top
|
|
126
|
+
if (timestampA > timestampB) {
|
|
127
|
+
return -1;
|
|
128
|
+
}
|
|
129
|
+
if (timestampB > timestampA) {
|
|
130
|
+
return 1;
|
|
131
|
+
}
|
|
132
|
+
return 0;
|
|
133
|
+
});
|
|
134
|
+
const postElements = posts.map((post, index) => (react_1.default.createElement(LiveBlogPost_1.LiveBlogPost, { key: `live-blog-post-${post.id}`, ...post, articleUrl: articleUrl, showShareButtons: showShareButtons, ad: ads[index], backToTop: this.props.backToTop })));
|
|
135
|
+
return (react_1.default.createElement("div", { className: "x-live-blog-wrapper", "data-live-blog-wrapper-id": id, ref: liveBlogWrapperElementRef }, postElements));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
const LiveBlogWrapper = withLiveBlogWrapperActions(BaseLiveBlogWrapper);
|
|
139
|
+
exports.LiveBlogWrapper = LiveBlogWrapper;
|
|
140
|
+
// This enables the component to work with x-interaction hydration
|
|
141
|
+
(0, x_interaction_1.registerComponent)(LiveBlogWrapper, 'LiveBlogWrapper');
|
|
142
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/LiveBlogWrapper/index.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.normalisePost = void 0;
|
|
4
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
5
|
+
//TODO: CI-1975 reset any types to something better, requires some digging
|
|
6
|
+
// Remove this helper when we no longer need to handle incoming WordPress events.
|
|
7
|
+
const normalisePost = (post) => {
|
|
8
|
+
if (post && !post.id && post.postId) {
|
|
9
|
+
post.id = post.postId;
|
|
10
|
+
}
|
|
11
|
+
return post;
|
|
12
|
+
};
|
|
13
|
+
exports.normalisePost = normalisePost;
|
|
14
|
+
//# sourceMappingURL=normalisePost.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalisePost.js","sourceRoot":"","sources":["../../../src/components/LiveBlogWrapper/normalisePost.ts"],"names":[],"mappings":";;;AAAA,uDAAuD;AACvD,0EAA0E;AAC1E,iFAAiF;AACjF,MAAM,aAAa,GAAG,CAAC,IAAS,EAAE,EAAE;IAClC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE;QACnC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,MAAM,CAAA;KACtB;IACD,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAEQ,sCAAa"}
|