Skip to content

Commit 27f3c3b

Browse files
authored
Merge pull request #14210 from guardian/doml/loop-video-fix-fallback
Fix Loop Video fallback image
2 parents e1b3eba + 07f31a7 commit 27f3c3b

File tree

5 files changed

+43
-30
lines changed

5 files changed

+43
-30
lines changed

dotcom-rendering/src/components/Card/Card.tsx

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -895,27 +895,21 @@ export const Card = ({
895895
)}
896896
{media.type === 'loop-video' && (
897897
<Island
898-
priority="feature"
898+
priority="critical"
899899
defer={{ until: 'visible' }}
900900
>
901901
<LoopVideo
902902
src={media.mainMedia.videoId}
903903
height={media.mainMedia.height}
904904
width={media.mainMedia.width}
905905
image={media.mainMedia.image ?? ''}
906-
fallbackImageComponent={
907-
<CardPicture
908-
mainImage={
909-
media.mainMedia.image ?? ''
910-
}
911-
imageSize={imageSize}
912-
loading={imageLoading}
913-
alt={media.imageAltText}
914-
aspectRatio={aspectRatio}
915-
/>
916-
}
917906
uniqueId={uniqueId}
918907
atomId={media.mainMedia.atomId}
908+
fallbackImage={media.mainMedia.image ?? ''}
909+
fallbackImageSize={imageSize}
910+
fallbackImageLoading={imageLoading}
911+
fallbackImageAlt={media.imageAltText}
912+
fallbackImageAspectRatio="5:4"
919913
/>
920914
</Island>
921915
)}

dotcom-rendering/src/components/CardPicture.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { generateSources, getFallbackSource } from './Picture';
99

1010
export type Loading = NonNullable<ImgHTMLAttributes<unknown>['loading']>;
1111

12-
type Props = {
12+
export type Props = {
1313
imageSize: ImageSizeType;
1414
mainImage: string;
1515
loading: Loading;

dotcom-rendering/src/components/LoopVideo.importable.tsx

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
customLoopPlayAudioEventName,
1515
customYoutubePlayEventName,
1616
} from '../lib/video';
17+
import { CardPicture, type Props as CardPictureProps } from './CardPicture';
1718
import { useConfig } from './ConfigContext';
1819
import type { PLAYER_STATES, PlayerStates } from './LoopVideoPlayer';
1920
import { LoopVideoPlayer } from './LoopVideoPlayer';
@@ -43,7 +44,11 @@ type Props = {
4344
width: number;
4445
height: number;
4546
image: string;
46-
fallbackImageComponent: JSX.Element;
47+
fallbackImage: CardPictureProps['mainImage'];
48+
fallbackImageSize: CardPictureProps['imageSize'];
49+
fallbackImageLoading: CardPictureProps['loading'];
50+
fallbackImageAlt: CardPictureProps['alt'];
51+
fallbackImageAspectRatio: CardPictureProps['aspectRatio'];
4752
};
4853

4954
export const LoopVideo = ({
@@ -53,7 +58,11 @@ export const LoopVideo = ({
5358
width,
5459
height,
5560
image,
56-
fallbackImageComponent,
61+
fallbackImage,
62+
fallbackImageSize,
63+
fallbackImageLoading,
64+
fallbackImageAlt,
65+
fallbackImageAspectRatio,
5766
}: Props) => {
5867
const adapted = useShouldAdapt();
5968
const { renderingTarget } = useConfig();
@@ -141,6 +150,16 @@ export const LoopVideo = ({
141150
}
142151
};
143152

153+
const FallbackImageComponent = (
154+
<CardPicture
155+
mainImage={fallbackImage}
156+
imageSize={fallbackImageSize}
157+
loading={fallbackImageLoading}
158+
aspectRatio={fallbackImageAspectRatio}
159+
alt={fallbackImageAlt}
160+
/>
161+
);
162+
144163
/**
145164
* Setup.
146165
*
@@ -333,7 +352,9 @@ export const LoopVideo = ({
333352

334353
if (renderingTarget !== 'Web') return null;
335354

336-
if (adapted) return fallbackImageComponent;
355+
if (adapted) {
356+
return FallbackImageComponent;
357+
}
337358

338359
const handlePlayPauseClick = (event: React.SyntheticEvent) => {
339360
event.preventDefault();
@@ -433,7 +454,7 @@ export const LoopVideo = ({
433454
width={width}
434455
height={height}
435456
posterImage={posterImage}
436-
fallbackImageComponent={fallbackImageComponent}
457+
FallbackImageComponent={FallbackImageComponent}
437458
currentTime={currentTime}
438459
setCurrentTime={setCurrentTime}
439460
ref={vidRef}

dotcom-rendering/src/components/LoopVideo.stories.tsx

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { breakpoints } from '@guardian/source/foundations';
22
import type { Meta, StoryObj } from '@storybook/react';
33
import { centreColumnDecorator } from '../../.storybook/decorators/gridDecorators';
4-
import { CardPicture } from './CardPicture';
54
import { LoopVideo } from './LoopVideo.importable';
65

76
export default {
@@ -21,24 +20,18 @@ export const Default = {
2120
args: {
2221
src: 'https://uploads.guim.co.uk/2025%2F06%2F20%2Ftesting+only%2C+please+ignore--3cb22b60-2c3f-48d6-8bce-38c956907cce-3.mp4',
2322
uniqueId: 'test-video-1',
23+
atomId: 'test-atom-1',
2424
height: 720,
2525
width: 900,
2626
image: 'https://media.guim.co.uk/9bdb802e6da5d3fd249b5060f367b3a817965f0c/0_0_1800_1080/master/1800.jpg',
27-
fallbackImageComponent: (
28-
<CardPicture
29-
mainImage="https://media.guim.co.uk/9bdb802e6da5d3fd249b5060f367b3a817965f0c/0_0_1800_1080/master/1800.jpg"
30-
imageSize="large"
31-
loading="eager"
32-
/>
33-
),
27+
fallbackImage: '',
3428
},
3529
} satisfies StoryObj<typeof LoopVideo>;
3630

3731
export const Without5to4Ratio = {
3832
name: 'Without 5:4 aspect ratio',
3933
args: {
4034
...Default.args,
41-
4235
src: 'https://uploads.guim.co.uk/2024/10/01/241001HeleneLoop_2.mp4',
4336
height: 1080,
4437
width: 1920,

dotcom-rendering/src/components/LoopVideoPlayer.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
import { css } from '@emotion/react';
22
import { space } from '@guardian/source/foundations';
33
import type { IconProps } from '@guardian/source/react-components';
4-
import type { Dispatch, SetStateAction, SyntheticEvent } from 'react';
4+
import type {
5+
Dispatch,
6+
ReactElement,
7+
SetStateAction,
8+
SyntheticEvent,
9+
} from 'react';
510
import { forwardRef } from 'react';
611
import { palette } from '../palette';
712
import { narrowPlayIconWidth, PlayIcon } from './Card/components/PlayIcon';
@@ -66,7 +71,7 @@ type Props = {
6671
uniqueId: string;
6772
width: number;
6873
height: number;
69-
fallbackImageComponent: JSX.Element;
74+
FallbackImageComponent: ReactElement;
7075
isPlayable: boolean;
7176
setIsPlayable: Dispatch<SetStateAction<boolean>>;
7277
playerState: PlayerStates;
@@ -95,7 +100,7 @@ export const LoopVideoPlayer = forwardRef(
95100
uniqueId,
96101
width,
97102
height,
98-
fallbackImageComponent,
103+
FallbackImageComponent,
99104
posterImage,
100105
isPlayable,
101106
setIsPlayable,
@@ -154,7 +159,7 @@ export const LoopVideoPlayer = forwardRef(
154159
{/* Only mp4 is currently supported. Assumes the video file type is mp4. */}
155160
{/* The start time is set to 1ms so that Safari will autoplay the video */}
156161
<source src={`${src}#t=0.001`} type="video/mp4" />
157-
{fallbackImageComponent}
162+
{FallbackImageComponent}
158163
</video>
159164
{ref && 'current' in ref && ref.current && isPlayable && (
160165
<>

0 commit comments

Comments
 (0)