Skip to content

Commit 4a259fc

Browse files
committed
Move immersive image to the top. Refactor immersive podcast card
1 parent a6c675e commit 4a259fc

File tree

1 file changed

+78
-109
lines changed

1 file changed

+78
-109
lines changed

dotcom-rendering/src/components/FeatureCard.tsx

Lines changed: 78 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { css } from '@emotion/react';
2-
import { from, space, until } from '@guardian/source/foundations';
3-
import { SvgMediaControlsPlay } from '@guardian/source/react-components';
2+
import { from, space } from '@guardian/source/foundations';
3+
import { Hide, SvgMediaControlsPlay } from '@guardian/source/react-components';
44
import { ArticleDesign, type ArticleFormat } from '../lib/articleFormat';
55
import { secondsToDuration } from '../lib/formatTime';
66
import { getZIndex } from '../lib/getZIndex';
@@ -180,10 +180,6 @@ const nonImmersivePodcastImageStyles = css`
180180
*/
181181
bottom: -${space[14]}px;
182182
left: ${space[2]}px;
183-
184-
${from.tablet} {
185-
display: none;
186-
}
187183
`;
188184

189185
const starRatingWrapper = css`
@@ -241,6 +237,35 @@ const getMedia = ({
241237
return undefined;
242238
};
243239

240+
const renderWaveform = (duration: string, bars: number) => (
241+
<div css={waveformStyles} className="waveform">
242+
<WaveForm seed={duration} height={64} bars={bars} barWidth={2} />
243+
</div>
244+
);
245+
246+
const renderPodcastImage = (
247+
image: string,
248+
alt: string,
249+
isImmersive: boolean,
250+
) => (
251+
<div css={podcastImageContainerStyles}>
252+
<div
253+
css={[
254+
podcastImageStyles,
255+
!isImmersive && nonImmersivePodcastImageStyles,
256+
]}
257+
>
258+
<CardPicture
259+
mainImage={image}
260+
imageSize="podcast"
261+
alt={alt}
262+
loading="lazy"
263+
aspectRatio="1:1"
264+
/>
265+
</div>
266+
</div>
267+
);
268+
244269
export type Props = {
245270
linkTo: string;
246271
format: ArticleFormat;
@@ -454,7 +479,6 @@ export const FeatureCard = ({
454479
imageSize={imageSize}
455480
alt={headlineText}
456481
loading={imageLoading}
457-
roundedCorners={false}
458482
aspectRatio={aspectRatio}
459483
mobileAspectRatio={
460484
mobileAspectRatio
@@ -470,7 +494,6 @@ export const FeatureCard = ({
470494
imageSize={imageSize}
471495
alt={media.imageAltText}
472496
loading={imageLoading}
473-
roundedCorners={false}
474497
aspectRatio={aspectRatio}
475498
mobileAspectRatio={
476499
mobileAspectRatio
@@ -504,44 +527,53 @@ export const FeatureCard = ({
504527
]}
505528
>
506529
{mainMedia?.type === 'Audio' &&
507-
!!mainMedia.podcastImage?.src && (
508-
<div
509-
css={
510-
podcastImageContainerStyles
511-
}
512-
>
513-
<div
514-
css={[
515-
podcastImageStyles,
516-
nonImmersivePodcastImageStyles,
517-
]}
518-
>
519-
<CardPicture
520-
mainImage={
521-
mainMedia
522-
.podcastImage
523-
.src
524-
}
525-
imageSize="podcast"
526-
alt={
527-
mainMedia
528-
.podcastImage
529-
.altText ?? ''
530-
}
531-
loading="lazy"
532-
roundedCorners={false}
533-
aspectRatio="1:1"
534-
/>
535-
</div>
536-
</div>
537-
)}
530+
!!mainMedia.podcastImage?.src &&
531+
(isImmersive ? (
532+
<Hide from="tablet">
533+
{renderPodcastImage(
534+
mainMedia.podcastImage.src,
535+
mainMedia.podcastImage
536+
.altText ?? '',
537+
false, // Immersive cards are styled as feature cards below the tablet viewport
538+
)}
539+
</Hide>
540+
) : (
541+
renderPodcastImage(
542+
mainMedia.podcastImage.src,
543+
mainMedia.podcastImage
544+
.altText ?? '',
545+
false,
546+
)
547+
))}
538548
<div
539549
css={[
540550
overlayStyles,
541551
isImmersive &&
542552
immersiveOverlayStyles,
543553
]}
544554
>
555+
{isImmersive &&
556+
mainMedia?.type === 'Audio' &&
557+
!!mainMedia.podcastImage?.src && (
558+
<div
559+
css={
560+
podcastImageContainerStyles
561+
}
562+
>
563+
<Hide until="tablet">
564+
{renderPodcastImage(
565+
mainMedia
566+
.podcastImage
567+
.src,
568+
mainMedia
569+
.podcastImage
570+
.altText ?? '',
571+
true,
572+
)}
573+
</Hide>
574+
</div>
575+
)}
576+
545577
{/**
546578
* Without the wrapping div the headline and byline would have space
547579
* inserted between them due to being direct children of the flex container
@@ -600,47 +632,6 @@ export const FeatureCard = ({
600632
</div>
601633
)}
602634

603-
{isImmersive &&
604-
mainMedia?.type === 'Audio' &&
605-
!!mainMedia.podcastImage?.src && (
606-
<div
607-
css={
608-
podcastImageContainerStyles
609-
}
610-
>
611-
<div
612-
css={[
613-
podcastImageStyles,
614-
css`
615-
${until.tablet} {
616-
display: none;
617-
}
618-
`,
619-
]}
620-
>
621-
<CardPicture
622-
mainImage={
623-
mainMedia
624-
.podcastImage
625-
.src
626-
}
627-
imageSize="podcast"
628-
alt={
629-
mainMedia
630-
.podcastImage
631-
.altText ??
632-
''
633-
}
634-
loading="lazy"
635-
roundedCorners={
636-
false
637-
}
638-
aspectRatio="1:1"
639-
/>
640-
</div>
641-
</div>
642-
)}
643-
644635
<CardFooter
645636
format={format}
646637
age={
@@ -690,21 +681,10 @@ export const FeatureCard = ({
690681
/>
691682

692683
{!isImmersive &&
693-
mainMedia?.type === 'Audio' && (
694-
<div
695-
css={waveformStyles}
696-
className="waveform"
697-
>
698-
<WaveForm
699-
seed={
700-
mainMedia.duration
701-
}
702-
height={64}
703-
// Just enough to cover the full width of the feature card in it's largest form
704-
bars={233}
705-
barWidth={2}
706-
/>
707-
</div>
684+
mainMedia?.type === 'Audio' &&
685+
renderWaveform(
686+
mainMedia.duration,
687+
233,
708688
)}
709689
</div>
710690
{/* On video article cards, the duration is displayed in the footer */}
@@ -726,20 +706,9 @@ export const FeatureCard = ({
726706
) : null}
727707
</div>
728708

729-
{isImmersive && mainMedia?.type === 'Audio' && (
730-
<div
731-
css={waveformStyles}
732-
className="waveform"
733-
>
734-
<WaveForm
735-
seed={mainMedia.duration}
736-
height={64}
737-
// Just enough to cover the full width of the feature card in it's largest form
738-
bars={314}
739-
barWidth={2}
740-
/>
741-
</div>
742-
)}
709+
{isImmersive &&
710+
mainMedia?.type === 'Audio' &&
711+
renderWaveform(mainMedia.duration, 313)}
743712
</div>
744713
)}
745714
</div>

0 commit comments

Comments
 (0)