1
1
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' ;
4
4
import { ArticleDesign , type ArticleFormat } from '../lib/articleFormat' ;
5
5
import { secondsToDuration } from '../lib/formatTime' ;
6
6
import { getZIndex } from '../lib/getZIndex' ;
@@ -180,10 +180,6 @@ const nonImmersivePodcastImageStyles = css`
180
180
*/
181
181
bottom : -${ space [ 14 ] } px;
182
182
left : ${ space [ 2 ] } px;
183
-
184
- ${ from . tablet } {
185
- display : none;
186
- }
187
183
` ;
188
184
189
185
const starRatingWrapper = css `
@@ -241,6 +237,35 @@ const getMedia = ({
241
237
return undefined ;
242
238
} ;
243
239
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
+
244
269
export type Props = {
245
270
linkTo : string ;
246
271
format : ArticleFormat ;
@@ -454,7 +479,6 @@ export const FeatureCard = ({
454
479
imageSize = { imageSize }
455
480
alt = { headlineText }
456
481
loading = { imageLoading }
457
- roundedCorners = { false }
458
482
aspectRatio = { aspectRatio }
459
483
mobileAspectRatio = {
460
484
mobileAspectRatio
@@ -470,7 +494,6 @@ export const FeatureCard = ({
470
494
imageSize = { imageSize }
471
495
alt = { media . imageAltText }
472
496
loading = { imageLoading }
473
- roundedCorners = { false }
474
497
aspectRatio = { aspectRatio }
475
498
mobileAspectRatio = {
476
499
mobileAspectRatio
@@ -504,44 +527,53 @@ export const FeatureCard = ({
504
527
] }
505
528
>
506
529
{ 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
+ ) ) }
538
548
< div
539
549
css = { [
540
550
overlayStyles ,
541
551
isImmersive &&
542
552
immersiveOverlayStyles ,
543
553
] }
544
554
>
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
+
545
577
{ /**
546
578
* Without the wrapping div the headline and byline would have space
547
579
* inserted between them due to being direct children of the flex container
@@ -600,47 +632,6 @@ export const FeatureCard = ({
600
632
</ div >
601
633
) }
602
634
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
-
644
635
< CardFooter
645
636
format = { format }
646
637
age = {
@@ -690,21 +681,10 @@ export const FeatureCard = ({
690
681
/>
691
682
692
683
{ ! 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 ,
708
688
) }
709
689
</ div >
710
690
{ /* On video article cards, the duration is displayed in the footer */ }
@@ -726,20 +706,9 @@ export const FeatureCard = ({
726
706
) : null }
727
707
</ div >
728
708
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 ) }
743
712
</ div >
744
713
) }
745
714
</ div >
0 commit comments