Skip to content
Merged
67 changes: 39 additions & 28 deletions dotcom-rendering/src/components/SelfHostedVideoInArticle.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { css } from '@emotion/react';
import { space } from '@guardian/source/foundations';
import type { FEAspectRatio } from '../frontend/feFront';
import type { ArticleFormat } from '../lib/articleFormat';
import {
Expand All @@ -10,12 +12,17 @@ import type { VideoPlayerFormat } from '../types/mainMedia';
import { Island } from './Island';
import { SelfHostedVideo } from './SelfHostedVideo.island';

const containerStyles = css`
margin-bottom: ${space[3]}px;
`;

type SelfHostedVideoInArticleProps = {
element: MediaAtomBlockElement;
format: ArticleFormat;
isMainMedia: boolean;
videoStyle: VideoPlayerFormat;
role?: RoleType;
caption?: string;
};

export const SelfHostedVideoInArticle = ({
Expand All @@ -24,10 +31,9 @@ export const SelfHostedVideoInArticle = ({
isMainMedia,
videoStyle,
role = 'inline',
caption,
}: SelfHostedVideoInArticleProps) => {
const posterImageUrl = element.posterImage?.[0]?.url;
const caption = element.title;

const sources = extractValidSourcesFromAssets(element.assets);
const aspectRatio = getAspectRatioFromSources(sources);
const firstVideoSource = sources[0];
Expand All @@ -37,31 +43,36 @@ export const SelfHostedVideoInArticle = ({
}

return (
<Island priority="critical" defer={{ until: 'visible' }}>
<SelfHostedVideo
atomId={element.id}
fallbackImage={posterImageUrl}
fallbackImageAlt={caption}
fallbackImageAspectRatio={
(firstVideoSource?.aspectRatio ?? '5:4') as FEAspectRatio
}
fallbackImageLoading="lazy"
fallbackImageSize="small"
aspectRatio={aspectRatio}
linkTo="Article-embed-MediaAtomBlockElement"
posterImage={posterImageUrl}
posterImageAspectRatio={firstVideoSource?.aspectRatio ?? '5:4'}
sources={sources}
subtitleSize="medium"
subtitleSource={getSubtitleAsset(element.assets)}
videoStyle={videoStyle}
uniqueId={element.id}
caption={caption}
format={format}
isMainMedia={isMainMedia}
role={role}
maxHeightDesktop={firstVideoSource?.height}
/>
</Island>
<div css={containerStyles}>
<Island priority="critical" defer={{ until: 'visible' }}>
<SelfHostedVideo
atomId={element.id}
fallbackImage={posterImageUrl}
fallbackImageAlt={caption}
fallbackImageAspectRatio={
(firstVideoSource?.aspectRatio ??
'5:4') as FEAspectRatio
}
fallbackImageLoading="lazy"
fallbackImageSize="small"
aspectRatio={aspectRatio}
linkTo="Article-embed-MediaAtomBlockElement"
posterImage={posterImageUrl}
posterImageAspectRatio={
firstVideoSource?.aspectRatio ?? '5:4'
}
sources={sources}
subtitleSize="medium"
subtitleSource={getSubtitleAsset(element.assets)}
videoStyle={videoStyle}
uniqueId={element.id}
caption={caption}
format={format}
isMainMedia={isMainMedia}
role={role}
maxHeightDesktop={firstVideoSource?.height}
/>
</Island>
</div>
);
};
10 changes: 8 additions & 2 deletions dotcom-rendering/src/components/VideoAtom.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { css } from '@emotion/react';
import { space } from '@guardian/source/foundations';
import type { ArticleFormat } from '../lib/articleFormat';
import { Caption } from './Caption';
import { MaintainAspectRatio } from './MaintainAspectRatio';

const figureStyles = css`
margin-bottom: ${space[3]}px;
`;

type AssetType = {
url: string;
mimeType?: string;
Expand Down Expand Up @@ -30,7 +36,7 @@ export const VideoAtom = ({
return null;
} // Handle empty assets array
return (
<>
<figure css={figureStyles}>
<MaintainAspectRatio
height={height}
width={width}
Expand Down Expand Up @@ -65,6 +71,6 @@ export const VideoAtom = ({
isMainMedia={isMainMedia}
/>
)}
</>
</figure>
);
};
6 changes: 6 additions & 0 deletions dotcom-rendering/src/frontend/schemas/feArticle.json
Original file line number Diff line number Diff line change
Expand Up @@ -2873,6 +2873,9 @@
},
"role": {
"$ref": "#/definitions/RoleType"
},
"caption": {
"type": "string"
}
},
"required": [
Expand Down Expand Up @@ -4066,6 +4069,9 @@
},
"role": {
"$ref": "#/definitions/RoleType"
},
"caption": {
"type": "string"
}
},
"required": [
Expand Down
5 changes: 3 additions & 2 deletions dotcom-rendering/src/lib/renderElement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,7 @@ export const renderElement = ({
isMainMedia={isMainMedia}
videoStyle={element.videoPlayerFormat}
role={element.role}
caption={element.caption ?? element.title}
/>
);
} else {
Expand All @@ -519,7 +520,7 @@ export const renderElement = ({
format={format}
assets={element.assets}
poster={element.posterImage?.[0]?.url}
caption={element.title}
caption={element.caption ?? element.title}
isMainMedia={isMainMedia}
/>
);
Expand Down Expand Up @@ -952,7 +953,7 @@ export const renderElement = ({
getLargestImageSize(element.posterImage ?? [])?.url
}
duration={element.duration}
mediaTitle={element.mediaTitle}
mediaTitle={element.caption ?? element.mediaTitle}
altText={element.altText}
origin={host}
stickyVideos={!!(isBlog && switches.stickyVideos)}
Expand Down
6 changes: 6 additions & 0 deletions dotcom-rendering/src/model/block-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2346,6 +2346,9 @@
},
"role": {
"$ref": "#/definitions/RoleType"
},
"caption": {
"type": "string"
}
},
"required": [
Expand Down Expand Up @@ -3539,6 +3542,9 @@
},
"role": {
"$ref": "#/definitions/RoleType"
},
"caption": {
"type": "string"
}
},
"required": [
Expand Down
2 changes: 2 additions & 0 deletions dotcom-rendering/src/types/content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,7 @@ export interface MediaAtomBlockElement {
duration?: number;
videoPlayerFormat?: VideoPlayerFormat;
role?: RoleType;
caption?: string;
}

export interface MultiImageBlockElement {
Expand Down Expand Up @@ -752,6 +753,7 @@ export interface YoutubeBlockElement {
overrideImage?: string;
altText?: string;
role?: RoleType;
caption?: string;
}

interface WitnessTypeDataBase {
Expand Down
Loading