diff --git a/data/mundo/live/c7dkx155e626t.json b/data/mundo/live/c7dkx155e626t.json
index 0f3d2dd9080..272e33c5fde 100644
--- a/data/mundo/live/c7dkx155e626t.json
+++ b/data/mundo/live/c7dkx155e626t.json
@@ -74,7 +74,15 @@
"serviceId": null,
"authToken": null,
"status": "LIVE",
- "warnings": null
+ "warnings": {
+ "warning_text": "Contains some upsetting scenes.",
+ "warning": [
+ {
+ "warning_code": "D1",
+ "short_description": "Some upsetting scenes"
+ }
+ ]
+ }
},
"leadMedia": true
}
diff --git a/src/app/components/LiveMediaStream/index.styles.tsx b/src/app/components/LiveMediaStream/index.styles.tsx
index 530e8c943ea..659b33563b2 100644
--- a/src/app/components/LiveMediaStream/index.styles.tsx
+++ b/src/app/components/LiveMediaStream/index.styles.tsx
@@ -1,8 +1,7 @@
import { css, Theme } from '@emotion/react';
-import PlayButton from '../MediaLoader/Placeholder/PlayButton';
export default {
- liveMediaStreamContainer: ({ palette, spacings, mq }: Theme) =>
+ liveMediaStreamContainer: ({ spacings }: Theme) =>
css({
// backgroundColor: `${palette.BLACK}`,
margin: `0 ${spacings.FULL}rem`,
@@ -23,7 +22,7 @@ export default {
width: '100%',
},
}),
- playButtonText: ({ spacings, palette, mq }: Theme) =>
+ playButtonText: ({ palette }: Theme) =>
css({
color: palette.WHITE,
}),
@@ -46,8 +45,16 @@ export default {
display: 'block',
width: '100%',
}),
- mediaLoaderContainer: ({ palette, spacings, mq }: Theme) =>
+ mediaLoaderContainer: ({ palette }: Theme) =>
css({
backgroundColor: `${palette.POSTBOX}`,
}),
+ showContent: () =>
+ css({
+ display: 'unset',
+ }),
+ hideContent: () =>
+ css({
+ display: 'none',
+ }),
};
diff --git a/src/app/components/LiveMediaStream/index.tsx b/src/app/components/LiveMediaStream/index.tsx
index e614bd03573..3e93c00aae5 100644
--- a/src/app/components/LiveMediaStream/index.tsx
+++ b/src/app/components/LiveMediaStream/index.tsx
@@ -1,9 +1,13 @@
/** @jsx jsx */
+/* @jsxFrag React.Fragment */
import { jsx } from '@emotion/react';
-import { useContext, useState } from 'react';
+import React, { FC, useContext, useEffect, useState } from 'react';
import Text from '#app/components/Text';
import { MediaCollection } from '#app/components/MediaLoader/types';
-import MediaLoader, { BumpLoader } from '#app/components/MediaLoader';
+import MediaLoader, {
+ BumpLoader,
+ ManualControlProps,
+} from '#app/components/MediaLoader';
import filterForBlockType from '#app/lib/utilities/blockHandlers';
import { ServiceContext } from '#app/contexts/ServiceContext';
import mediaIcons from '#psammead/psammead-assets/src/svgs/mediaIcons';
@@ -34,46 +38,76 @@ const LiveMediaStream = ({ mediaCollection }: Props) => {
},
} = mediaItem;
- const handleClick = () => {
- setShowMedia(!showMedia);
- };
+ const ManualControls = ({
+ mediaControls,
+ mediaContainer,
+ }: ManualControlProps) => {
+ const handleClick = () => {
+ setShowMedia(previousState => !previousState);
+ };
- return (
-
-
-
{short}
- {!showMedia && (
+ useEffect(() => {
+ if (showMedia) {
+ mediaControls?.play();
+ } else {
+ mediaControls?.stop();
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [mediaControls, showMedia]);
+
+ return (
+ <>
+
+ {`${title} - ${networkName}`}
+
+
- )}
- {showMedia && (
-
-
- {`${title} - ${networkName}`}
-
-
-
+
+ {mediaContainer}
- )}
+ >
+ );
+ };
+
+ return (
+
);
};
diff --git a/src/app/components/MediaLoader/configs/liveMedia.ts b/src/app/components/MediaLoader/configs/liveMedia.ts
index ca5636dcca7..a5186cea2f8 100644
--- a/src/app/components/MediaLoader/configs/liveMedia.ts
+++ b/src/app/components/MediaLoader/configs/liveMedia.ts
@@ -33,7 +33,7 @@ export default ({
return {
playerConfig: {
...basePlayerConfig,
- autoplay: true,
+ autoplay: false,
statsObject: {
...basePlayerConfig.statsObject,
episodePID: liveMediaBlock.id,
diff --git a/src/app/components/MediaLoader/index.tsx b/src/app/components/MediaLoader/index.tsx
index 2e4a92a0548..ca315c0459c 100644
--- a/src/app/components/MediaLoader/index.tsx
+++ b/src/app/components/MediaLoader/index.tsx
@@ -1,8 +1,14 @@
/** @jsx jsx */
/* @jsxFrag React.Fragment */
-
import { jsx } from '@emotion/react';
-import React, { useContext, useEffect, useRef, useState } from 'react';
+import React, {
+ FC,
+ ReactHTMLElement,
+ useContext,
+ useEffect,
+ useRef,
+ useState,
+} from 'react';
import { Helmet } from 'react-helmet';
import { RequestContext } from '#contexts/RequestContext';
import { MEDIA_PLAYER_STATUS } from '#app/lib/logger.const';
@@ -16,7 +22,7 @@ import {
import filterForBlockType from '#lib/utilities/blockHandlers';
import { PageTypes } from '#app/models/types/global';
import { EventTrackingContext } from '#app/contexts/EventTrackingContext';
-import { BumpType, MediaBlock, PlayerConfig } from './types';
+import { BumpType, MediaBlock, Player, PlayerConfig } from './types';
import Caption from '../Caption';
import nodeLogger from '../../lib/logger.node';
import buildConfig from './utils/buildSettings';
@@ -93,13 +99,24 @@ const AdvertTagLoader = () => {
);
};
+export type ManualControlProps = {
+ mediaControls?: Player;
+ mediaContainer: ReactHTMLElement
;
+};
+
type MediaContainerProps = {
playerConfig: PlayerConfig;
showAds: boolean;
+ ManualControls?: FC;
};
-const MediaContainer = ({ playerConfig, showAds }: MediaContainerProps) => {
+const MediaContainer = ({
+ playerConfig,
+ showAds,
+ ManualControls,
+}: MediaContainerProps) => {
const playerElementRef = useRef(null);
+ const [mediaControls, setMediaControls] = useState();
useEffect(() => {
try {
@@ -111,6 +128,7 @@ const MediaContainer = ({ playerConfig, showAds }: MediaContainerProps) => {
);
mediaPlayer.load();
+ setMediaControls(mediaPlayer);
if (showAds) {
const adTag = await window.dotcom.ads.getAdTag();
@@ -145,7 +163,7 @@ const MediaContainer = ({ playerConfig, showAds }: MediaContainerProps) => {
}
}, [playerConfig, showAds]);
- return (
+ const container = (
{
}
/>
);
+
+ return (
+ <>
+ {ManualControls ? (
+
+ ) : (
+ container
+ )}
+ >
+ );
};
type Props = {
blocks: MediaBlock[];
className?: string;
embedded?: boolean;
+ placeholderOverride?: boolean;
+ ManualControls?: FC
;
};
-const MediaLoader = ({ blocks, className, embedded }: Props) => {
+const MediaLoader = ({
+ blocks,
+ className,
+ embedded,
+ placeholderOverride = true,
+ ManualControls,
+}: Props) => {
const { lang, translations } = useContext(ServiceContext);
const { pageIdentifier } = useContext(EventTrackingContext);
const { enabled: adsEnabled } = useToggle('ads');
@@ -225,7 +264,9 @@ const MediaLoader = ({ blocks, className, embedded }: Props) => {
mediaInfo,
} = placeholderConfig ?? {};
- const hasPlaceholder = Boolean(showPlaceholder && placeholderSrc);
+ const hasPlaceholder = Boolean(
+ placeholderOverride && showPlaceholder && placeholderSrc,
+ );
const showPortraitTitle = orientation === 'portrait' && !embedded;
@@ -274,7 +315,11 @@ const MediaLoader = ({ blocks, className, embedded }: Props) => {
onClick={() => setShowPlaceholder(false)}
/>
) : (
-
+
)}
>
)}
diff --git a/src/app/components/MediaLoader/types.ts b/src/app/components/MediaLoader/types.ts
index af18d67edac..69588e34048 100644
--- a/src/app/components/MediaLoader/types.ts
+++ b/src/app/components/MediaLoader/types.ts
@@ -114,6 +114,9 @@ export type Player = {
parameters: { updatedAdTag: string },
): void;
load: () => void;
+ play: () => void;
+ pause: () => void;
+ stop: () => void;
bind: (event: string, callback: () => void) => void;
loadPlugin: (
pluginName: { [key: string]: string },
diff --git a/src/app/models/types/translations.ts b/src/app/models/types/translations.ts
index 29277854c94..6dd5734a914 100644
--- a/src/app/models/types/translations.ts
+++ b/src/app/models/types/translations.ts
@@ -173,7 +173,7 @@ export interface Translations {
recentEpisodes?: string;
podcastExternalLinks?: string;
download?: string;
- watchNow: string;
+ watchNow?: string;
};
socialEmbed: {
caption?: {
diff --git a/ws-nextjs-app/pages/[service]/live/[id]/Header/index.tsx b/ws-nextjs-app/pages/[service]/live/[id]/Header/index.tsx
index 7057263cf46..5cae4153cbe 100644
--- a/ws-nextjs-app/pages/[service]/live/[id]/Header/index.tsx
+++ b/ws-nextjs-app/pages/[service]/live/[id]/Header/index.tsx
@@ -3,12 +3,8 @@ import { jsx } from '@emotion/react';
import Heading from '#app/components/Heading';
import Text from '#app/components/Text';
import MaskedImage from '#app/components/MaskedImage';
-import MediaLoader, { BumpLoader } from '#app/components/MediaLoader';
-import { MediaBlock, MediaCollection } from '#app/components/MediaLoader/types';
-import { useContext, useState } from 'react';
-import mediaIcons from '#psammead/psammead-assets/src/svgs/mediaIcons';
-import Helmet from 'react-helmet';
-import { ServiceContext } from '#app/contexts/ServiceContext';
+import { MediaCollection } from '#app/components/MediaLoader/types';
+import LiveMediaStream from '#app/components/LiveMediaStream';
import LiveLabelHeader from './LiveLabelHeader';
import styles from './styles';
@@ -29,7 +25,6 @@ const Header = ({
imageWidth?: number;
mediaCollections?: MediaCollection[] | null;
}) => {
- const { translations } = useContext(ServiceContext);
const isHeaderImage = !!imageUrl && !!imageUrlTemplate && !!imageWidth;
const Title = (
@@ -40,20 +35,8 @@ const Header = ({
);
- const [showMedia, setShowMedia] = useState(false);
-
- const handleClick = () => {
- setShowMedia(!showMedia);
- };
-
return (
-
-
-
@@ -101,41 +84,29 @@ const Header = ({
)}
{mediaCollections && (
-
-
- {showMedia && (
-
- {mediaCollections[0].model.title}
- {' - '}
- {mediaCollections[0].model.masterbrand.networkName}
-
- )}
-
- )}
- {mediaCollections && showMedia && (
-
+
)}