epicViewLog: getEpicViewLog()

in dotcom-rendering/src/components/LiveBlogEpic.importable.tsx [126:279]


			epicViewLog: getEpicViewLog(storage.local),
			weeklyArticleHistory: articleCounts?.weeklyArticleHistory,
			hasOptedOutOfArticleCount,
			url: window.location.origin + window.location.pathname,
			isSignedIn,
			pageId,
		},
	};
};

/**
 * Render
 *
 * Dynamically imports and renders a given module
 *
 * @param props
 * @param name string - The name of the component
 * @param props.props object - The props of the component
 * @returns The resulting react component
 */
const Render = ({ name, props }: { name: string; props: EpicProps }) => {
	const { Epic } = useEpic({ name });

	if (isUndefined(Epic)) return null;
	log('dotcom', 'LiveBlogEpic has the Epic');

	return (
		<aside
			css={css`
				margin-bottom: ${space[3]}px;
			`}
		>
			{}
			<Epic {...props} />
		</aside>
	);
};

/**
 * Using the payload, make a fetch request to contributions service
 */
const Fetch = ({
	payload,
	contributionsServiceUrl,
	ophanPageViewId,
	renderingTarget,
	pageUrl,
}: {
	payload: EpicPayload;
	contributionsServiceUrl: string;
	ophanPageViewId: string;
	renderingTarget: RenderingTarget;
	pageUrl: string;
}) => {
	const response = useSDCLiveblogEpic(contributionsServiceUrl, payload);

	// If we didn't get a module in response (or we're still waiting) do nothing. If
	// no epic should be shown the response is equal to {}, hence the Object.keys
	if (!response?.data || Object.keys(response).length === 0) {
		return null;
	}
	log('dotcom', 'LiveBlogEpic has a module');

	const { props } = response.data.module;

	const tracking: Tracking = {
		...props.tracking,
		ophanPageId: ophanPageViewId,
		platformId: 'GUARDIAN_WEB',
		referrerUrl: pageUrl,
	};

	// Add submitComponentEvent function to props to enable Ophan tracking in the component
	const enrichedProps: EpicProps = {
		...props,
		tracking,
		submitComponentEvent: (componentEvent: OphanComponentEvent) =>
			submitComponentEvent(componentEvent, renderingTarget),
	};

	// Take any returned module and render it
	return <Render name={response.data.module.name} props={enrichedProps} />;
};

function insertAfter(referenceNode: HTMLElement, newNode: Element) {
	referenceNode.parentNode?.insertBefore(newNode, referenceNode.nextSibling);
}

/**
 * LiveBlogEpic is the support epic which appears in-between blocks in blogs
 *
 * There are three main steps to create this epic:
 *
 * 1. usePayload - Build the payload. The config object we send to contributions
 * 2. Fetch - POST the payload to the contributions endpoint
 * 3. Render - Take the props and name data we got in response to our fetch and dynamically import
 *    and render the Epic component using it
 *
 * ## Why does this need to be an Island?
 *
 * All behaviour is client-side.
 *
 * ---
 *
 * (No visual story exist)
 */
export const LiveBlogEpic = ({
	sectionId,
	shouldHideReaderRevenue,
	isPaidContent,
	tags,
	contributionsServiceUrl,
	pageId,
	keywordIds,
	renderingTarget,
}: Props) => {
	log('dotcom', 'LiveBlogEpic started');

	const ophanPageViewId = usePageViewId(renderingTarget);

	const [pageUrl, setPageUrl] = useState<string | undefined>();

	useEffect(() => {
		setPageUrl(window.location.origin + window.location.pathname);
	}, []);

	// First construct the payload
	const payload = usePayload({
		shouldHideReaderRevenue,
		sectionId,
		isPaidContent,
		tags,
		pageId,
		keywordIds,
	});
	if (!ophanPageViewId || !payload || !pageUrl) return null;

	/**
	 * Here we decide where to insert the epic.
	 *
	 * If the url contains a permalink then we
	 * want to insert it immediately after that block to prevent any CLS issues.
	 *
	 * Otherwise, we choose a random position near the top of the blog
	 */
	const epicPlaceholder = document.createElement('article');
	if (window.location.href.includes('#block-')) {
		// Because we're using a permalink there's a possibility the epic will render in
		// view. To prevent confusing layout shift we initially hide the message so that
		// we can reveal (animate in) it once it has been rendered
		epicPlaceholder.classList.add('pending');
		const blockId = window.location.hash.slice(1);
		const blockLinkedTo = document.getElementById(blockId);
		if (blockLinkedTo) {