11import { css } from '@emotion/react' ;
22import { isUndefined } from '@guardian/libs' ;
33import { between , from , space , until } from '@guardian/source/foundations' ;
4- import { Hide , Link , SvgCamera } from '@guardian/source/react-components' ;
4+ import { Hide } from '@guardian/source/react-components' ;
55import {
66 ArticleDesign ,
77 type ArticleFormat ,
88 ArticleSpecial ,
99} from '../../lib/articleFormat' ;
1010import { isMediaCard } from '../../lib/cardHelpers' ;
11- import { isWithinTwelveHours , secondsToDuration } from '../../lib/formatTime' ;
11+ import { secondsToDuration } from '../../lib/formatTime' ;
1212import { appendLinkNameMedia } from '../../lib/getDataLinkName' ;
1313import { getZIndex } from '../../lib/getZIndex' ;
1414import { getOphanComponents } from '../../lib/labs' ;
15- import { DISCUSSION_ID_DATA_ATTRIBUTE } from '../../lib/useCommentCount' ;
1615import { BETA_CONTAINERS } from '../../model/enhanceCollections' ;
1716import { palette } from '../../palette' ;
1817import type { Branding } from '../../types/branding' ;
@@ -31,7 +30,6 @@ import type { MainMedia } from '../../types/mainMedia';
3130import type { OnwardsSource } from '../../types/onwards' ;
3231import { Avatar } from '../Avatar' ;
3332import { BrandingLabel } from '../BrandingLabel' ;
34- import { CardCommentCount } from '../CardCommentCount.importable' ;
3533import { CardHeadline , type ResponsiveFontSize } from '../CardHeadline' ;
3634import type { Loading } from '../CardPicture' ;
3735import { CardPicture } from '../CardPicture' ;
@@ -50,8 +48,7 @@ import { SupportingKeyStoriesContent } from '../SupportingKeyStoriesContent';
5048import { SvgMediaControlsPlay } from '../SvgMediaControlsPlay' ;
5149import { YoutubeBlockComponent } from '../YoutubeBlockComponent.importable' ;
5250import { AvatarContainer } from './components/AvatarContainer' ;
53- import { CardAge } from './components/CardAge' ;
54- import { CardFooter } from './components/CardFooter' ;
51+ import { CardFooter } from './components/CardFooterNew' ;
5552import {
5653 CardLayout ,
5754 decideAvatarPosition ,
@@ -337,14 +334,6 @@ const decideSublinkPosition = (
337334 return alignment === 'vertical' ? 'inner' : 'outer' ;
338335} ;
339336
340- const liveBulletStyles = css `
341- width : 9px ;
342- height : 9px ;
343- border-radius : 50% ;
344- background-color : ${ palette ( '--pill-bullet' ) } ;
345- margin-right : ${ space [ 1 ] } px;
346- ` ;
347-
348337export const Card = ( {
349338 linkTo,
350339 format,
@@ -431,143 +420,6 @@ export const Card = ({
431420 */
432421 const isVideoArticle = format . design === ArticleDesign . Video ;
433422
434- const isLabs = format . theme === ArticleSpecial . Labs ;
435-
436- const decideAge = ( ) => {
437- if ( ! webPublicationDate ) return undefined ;
438- const withinTwelveHours = isWithinTwelveHours ( webPublicationDate ) ;
439-
440- const shouldShowAge =
441- isStorylines ||
442- isTagPage ||
443- ! ! onwardsSource ||
444- ( showAge && withinTwelveHours ) ;
445-
446- if ( ! shouldShowAge ) return undefined ;
447-
448- return (
449- < CardAge
450- webPublication = { {
451- date : webPublicationDate ,
452- isWithinTwelveHours : withinTwelveHours ,
453- } }
454- showClock = { showClock }
455- serverTime = { serverTime }
456- isTagPage = { isTagPage }
457- />
458- ) ;
459- } ;
460-
461- const CommentCount = ( ) =>
462- ! ! discussionId && (
463- < Link
464- { ...{
465- [ DISCUSSION_ID_DATA_ATTRIBUTE ] : discussionId ,
466- } }
467- data-ignore = "global-link-styling"
468- data-link-name = "Comment count"
469- href = { `${ linkTo } #comments` }
470- cssOverrides = { css `
471- /* See: https://css-tricks.com/nested-links/ */
472- z-index : ${ getZIndex ( 'card-nested-link' ) } ;
473- /* The following styles turn off those provided by Link */
474- color : inherit;
475- /* stylelint-disable-next-line property-disallowed-list */
476- font-family : inherit;
477- font-size : inherit;
478- line-height : inherit;
479- text-decoration : none;
480- min-height : 10px ;
481- ` }
482- >
483- < Island priority = "feature" defer = { { until : 'visible' } } >
484- < CardCommentCount
485- discussionApiUrl = { discussionApiUrl }
486- discussionId = { discussionId }
487- />
488- </ Island >
489- </ Link >
490- ) ;
491-
492- const MediaOrNewsletterPill = ( ) => (
493- < div
494- css = { css `
495- margin-top : auto;
496- display : flex;
497- ${ isStorylines &&
498- `
499- flex-direction: column;
500- gap: ${ space [ 1 ] } px;
501- align-items: flex-start;
502- ` }
503- ` }
504- >
505- { /* Usually, we either display the pill or the footer,
506- but if the card appears in the storylines section on tag pages
507- then we do want to display the date on these cards as well as the media pill.
508- */ }
509- { isStorylines && (
510- < CardFooter
511- format = { format }
512- age = { decideAge ( ) }
513- commentCount = { < CommentCount /> }
514- cardBranding = {
515- isOnwardContent ? < LabsBranding /> : undefined
516- }
517- showLivePlayable = { showLivePlayable }
518- />
519- ) }
520-
521- { mainMedia ?. type === 'YoutubeVideo' && isVideoArticle && (
522- < >
523- { mainMedia . isLive ? (
524- < Pill
525- content = "Live"
526- icon = { < div css = { liveBulletStyles } /> }
527- />
528- ) : (
529- < Pill
530- content = { secondsToDuration ( mainMedia . duration ) }
531- icon = { < SvgMediaControlsPlay width = { 18 } /> }
532- prefix = "Video"
533- />
534- ) }
535- </ >
536- ) }
537- { mainMedia ?. type === 'Audio' && (
538- < Pill
539- content = { mainMedia . duration }
540- icon = { < SvgMediaControlsPlay width = { 18 } /> }
541- prefix = "Podcast"
542- />
543- ) }
544- { mainMedia ?. type === 'Gallery' && (
545- < Pill
546- content = { mainMedia . count }
547- icon = { < SvgCamera /> }
548- prefix = "Gallery"
549- />
550- ) }
551- { mainMedia ?. type === 'SelfHostedVideo' &&
552- ( format . design === ArticleDesign . Video ? (
553- < Pill
554- content = ""
555- icon = { < SvgMediaControlsPlay width = { 18 } /> }
556- prefix = "Video"
557- />
558- ) : format . design === ArticleDesign . Audio ? (
559- < Pill
560- content = ""
561- icon = { < SvgMediaControlsPlay width = { 18 } /> }
562- prefix = "Podcast"
563- />
564- ) : format . design === ArticleDesign . Gallery ? (
565- < Pill content = "" icon = { < SvgCamera /> } prefix = "Gallery" />
566- ) : null ) }
567- { isNewsletter && < Pill content = "Newsletter" /> }
568- </ div >
569- ) ;
570-
571423 if ( snapData ?. embedHtml ) {
572424 return (
573425 < SnapCssSandbox snapData = { snapData } >
@@ -873,7 +725,7 @@ export const Card = ({
873725 alignment = "end"
874726 ophanComponentLink = { dataAttributes ?. ophanComponentLink }
875727 ophanComponentName = { dataAttributes ?. ophanComponentName }
876- isLabs = { isLabs }
728+ isLabs = { format . theme === ArticleSpecial . Labs }
877729 dataTestId = "card-branding-logo"
878730 />
879731 </ div >
@@ -896,7 +748,7 @@ export const Card = ({
896748 alignment = "end"
897749 ophanComponentLink = { dataAttributes ?. ophanComponentLink }
898750 ophanComponentName = { dataAttributes ?. ophanComponentName }
899- isLabs = { isLabs }
751+ isLabs = { format . theme === ArticleSpecial . Labs }
900752 />
901753 </ div >
902754 </ >
@@ -1300,33 +1152,28 @@ export const Card = ({
13001152 />
13011153 ) }
13021154
1155+ { /** Footer rendered inside the card boundary */ }
13031156 { ! isOpinionCardWithAvatar && (
1304- < >
1305- { showPill ? (
1306- < >
1307- { ! ! branding &&
1308- format . theme ===
1309- ArticleSpecial . Labs &&
1310- isOnwardContent && (
1311- < LabsBranding />
1312- ) }
1313- < MediaOrNewsletterPill />
1314- </ >
1315- ) : (
1316- < CardFooter
1317- format = { format }
1318- age = { decideAge ( ) }
1319- commentCount = { < CommentCount /> }
1320- cardBranding = {
1321- isOnwardContent ? (
1322- < LabsBranding />
1323- ) : undefined
1324- }
1325- showLivePlayable = { showLivePlayable }
1326- />
1327- ) }
1328- </ >
1157+ < CardFooter
1158+ format = { format }
1159+ showLivePlayable = { showLivePlayable }
1160+ showAge = { showAge }
1161+ cardBranding = { < LabsBranding /> }
1162+ mainMedia = { mainMedia }
1163+ isNewsletter = { isNewsletter }
1164+ showPill = { showPill }
1165+ isStorylines = { isStorylines }
1166+ onwardsSource = { onwardsSource }
1167+ webPublicationDate = { webPublicationDate }
1168+ showClock = { showClock }
1169+ serverTime = { serverTime }
1170+ isTagPage = { isTagPage }
1171+ discussionId = { discussionId }
1172+ discussionApiUrl = { discussionApiUrl }
1173+ linkTo = { linkTo }
1174+ />
13291175 ) }
1176+
13301177 { showLivePlayable &&
13311178 liveUpdatesPosition === 'inner' && (
13321179 < Island
@@ -1413,20 +1260,28 @@ export const Card = ({
14131260 { isOpinionCardWithAvatar && (
14141261 < CardFooter
14151262 format = { format }
1416- age = { decideAge ( ) }
1417- commentCount = { < CommentCount /> }
14181263 showLivePlayable = { showLivePlayable }
1264+ showAge = { showAge }
1265+ cardBranding = { < LabsBranding /> }
1266+ mainMedia = { mainMedia }
1267+ isNewsletter = { isNewsletter }
14191268 shouldReserveSpace = { {
14201269 mobile : avatarPosition . mobile === 'bottom' ,
14211270 desktop : avatarPosition . desktop === 'bottom' ,
14221271 } }
1272+ showPill = { showPill }
1273+ isStorylines = { isStorylines }
1274+ onwardsSource = { onwardsSource }
1275+ webPublicationDate = { webPublicationDate }
1276+ showClock = { showClock }
1277+ serverTime = { serverTime }
1278+ isTagPage = { isTagPage }
1279+ discussionId = { discussionId }
1280+ discussionApiUrl = { discussionApiUrl }
1281+ linkTo = { linkTo }
14231282 />
14241283 ) }
14251284 </ div >
1426-
1427- { ! isOnwardContent && format . theme === ArticleSpecial . Labs && (
1428- < LabsBranding />
1429- ) }
14301285 </ CardWrapper >
14311286 ) ;
14321287} ;
0 commit comments