Skip to content

Commit

Permalink
[NHUB-315] (2.4.2): Support Audio & Video for Featuremedia (#615)
Browse files Browse the repository at this point in the history
* Support video seeking

* Update utils

* Update usage of featuremedia & other media fields

* Update video & audio src attributes in body_html

* Make audio use available width

* Update ItemIcons to generate list of icon types automatically

* remove commented line

* fix flake8 issues
  • Loading branch information
MarkLark86 authored Oct 23, 2023
1 parent 3b294de commit a0dfbc6
Show file tree
Hide file tree
Showing 18 changed files with 135 additions and 93 deletions.
4 changes: 1 addition & 3 deletions assets/components/cards/render/CardFooter.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,17 @@ import React from 'react';
import PropTypes from 'prop-types';
import CardMeta from './CardMeta';

function CardFooter({item, picture, listConfig}) {
function CardFooter({item, listConfig}) {
return (<div className="card-footer">
<CardMeta
item={item}
picture={picture}
listConfig={listConfig}
/>
</div>);
}

CardFooter.propTypes = {
item: PropTypes.object.isRequired,
picture: PropTypes.object,
listConfig: PropTypes.object,
};

Expand Down
5 changes: 2 additions & 3 deletions assets/components/cards/render/CardMeta.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import {gettext, shortDate, fullDate, isDisplayed} from 'utils';
import {characterCount, wordCount} from 'utils';
import WireListItemIcons from 'wire/components/WireListItemIcons';

function CardMeta({item, picture, displayDivider, slugline, listConfig}) {
function CardMeta({item, displayDivider, slugline, listConfig}) {
return (<div className="wire-articles__item__meta">
<WireListItemIcons item={item} picture={picture} divider={displayDivider} />
<WireListItemIcons item={item} divider={displayDivider} />
<div className="wire-articles__item__meta-info">
{slugline && <span className='bold'>{slugline}</span>}
<span>
Expand All @@ -26,7 +26,6 @@ function CardMeta({item, picture, displayDivider, slugline, listConfig}) {

CardMeta.propTypes = {
item: PropTypes.object.isRequired,
picture: PropTypes.object,
displayDivider: PropTypes.bool,
slugline: PropTypes.string,
listConfig: PropTypes.object,
Expand Down
1 change: 0 additions & 1 deletion assets/components/cards/render/LargePictureTextCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ const getPictureTextPanel = (item, picture, openItem, cardId, listConfig) => {
<CardBody item={item} displaySource={false} listConfig={listConfig} />
<CardFooter
item={item}
picture={picture}
listConfig={listConfig}
/>
</div>
Expand Down
2 changes: 0 additions & 2 deletions assets/components/cards/render/LargeTextOnlyCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@ import PropTypes from 'prop-types';
import CardFooter from './CardFooter';
import CardBody from './CardBody';
import CardRow from './CardRow';
import {getPicture} from 'wire/utils';

const getTextOnlyPanel = (item, openItem, cardId, listConfig) => (
<div key={item._id} className='col-sm-6 col-lg-4 d-flex mb-4'>
<div className='card card--home' onClick={() => openItem(item, cardId)}>
<CardBody item={item} displaySource={false} listConfig={listConfig} />
<CardFooter
item={item}
picture={getPicture(item)}
listConfig={listConfig}
/>
</div>
Expand Down
1 change: 0 additions & 1 deletion assets/components/cards/render/PictureTextCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ const getPictureTextPanel = (item, picture, openItem, withPictures, cardId, list
<CardBody item={item} displayMeta={false} listConfig={listConfig} />
<CardFooter
item={item}
picture={rendition}
listConfig={listConfig}
/>
</div>
Expand Down
7 changes: 3 additions & 4 deletions assets/components/cards/render/TextOnlyCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import React from 'react';
import PropTypes from 'prop-types';
import CardRow from './CardRow';
import CardFooter from './CardFooter';
import {getPicture, shortText} from 'wire/utils';
import {shortText} from 'wire/utils';
import {Embargo} from '../../../wire/components/fields/Embargo';

const getTextOnlyPanel = (item, openItem, picture, cardId, listConfig) => (
const getTextOnlyPanel = (item, openItem, cardId, listConfig) => (
<div key={item._id} className='col-sm-6 col-md-4 col-lg-3 col-xxl-2 d-flex mb-4'>
<div className='card card--home' onClick={() => openItem(item, cardId)}>
<div className='card-body'>
Expand All @@ -17,7 +17,6 @@ const getTextOnlyPanel = (item, openItem, picture, cardId, listConfig) => (
</div>
<CardFooter
item={item}
picture={picture}
listConfig={listConfig}
/>
</div>
Expand All @@ -28,7 +27,7 @@ const getTextOnlyPanel = (item, openItem, picture, cardId, listConfig) => (
function TextOnlyCard ({items, title, product, openItem, isActive, cardId, listConfig}) {
return (
<CardRow title={title} product={product} isActive={isActive}>
{items.map((item) => getTextOnlyPanel(item, openItem, getPicture(item), cardId, listConfig))}
{items.map((item) => getTextOnlyPanel(item, openItem, cardId, listConfig))}
</CardRow>
);
}
Expand Down
2 changes: 0 additions & 2 deletions assets/components/cards/render/TopNewsOneByOneCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import CardMeta from './CardMeta';
import {Embargo} from '../../../wire/components/fields/Embargo';

const getTopNewsPanel = (item, picture, openItem, cardId, listConfig) => {

const rendition = getThumbnailRendition(picture, true);
const imageUrl = rendition && rendition.href;
const caption = rendition && getCaption(picture);
Expand All @@ -19,7 +18,6 @@ const getTopNewsPanel = (item, picture, openItem, cardId, listConfig) => {
<Embargo item={item} isCard={true} />
<CardMeta
item={item}
picture={picture}
listConfig={listConfig}
displayDivider={false}
/>
Expand Down
8 changes: 1 addition & 7 deletions assets/components/cards/render/TopNewsTwoByTwoCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import CardBody from './CardBody';
import {Embargo} from '../../../wire/components/fields/Embargo';

const getTopNewsLeftPanel = (item, picture, openItem, cardId, listConfig) => {

const rendition = getThumbnailRendition(picture, true);
const imageUrl = rendition && rendition.href;
const caption = rendition && getCaption(picture);
Expand All @@ -24,7 +23,6 @@ const getTopNewsLeftPanel = (item, picture, openItem, cardId, listConfig) => {
<Embargo item={item} isCard={true} />
<CardMeta
item={item}
picture={picture}
displayDivider={false}
slugline={getSlugline(item, true)}
/>
Expand All @@ -38,7 +36,6 @@ const getTopNewsLeftPanel = (item, picture, openItem, cardId, listConfig) => {
};

const getTopNewsRightPanel = (item, picture, openItem, cardId, listConfig) => {

const rendition = getThumbnailRendition(picture);
const imageUrl = rendition && rendition.href;
const caption = rendition && getCaption(picture);
Expand All @@ -47,10 +44,7 @@ const getTopNewsRightPanel = (item, picture, openItem, cardId, listConfig) => {
<div className='card card--home' onClick={() => openItem(item, cardId)}>
<img className='card-img-top' src={imageUrl} alt={caption} />
<CardBody item={item} displayDescription={false} displaySource={false} listConfig={listConfig}/>
<CardFooter
item={item}
picture={picture}
/>
<CardFooter item={item} />
</div>
</div>);
};
Expand Down
3 changes: 3 additions & 0 deletions assets/styles/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2945,6 +2945,9 @@ a.wire-articles__versions {
width: 100%;
height: auto;
}
audio {
width: 100%;
};
.btn {
align-self: flex-end;
}
Expand Down
14 changes: 9 additions & 5 deletions assets/ui/components/ArticleBodyHtml.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -162,19 +162,23 @@ class ArticleBodyHtml extends React.PureComponent {

container.innerHTML = html;
container
.querySelectorAll('img')
.forEach((imageTag) => {
.querySelectorAll('img, video, audio')
.forEach((mediaTag) => {
// Using the tag's `src` attribute, find the Original Rendition's ID
const originalMediaId = imageEmbedOriginalIds.find((mediaId) => (
!imageTag.src.startsWith('/assets/') &&
imageTag.src.includes(mediaId))
!mediaTag.src.startsWith('/assets/') &&
mediaTag.src.includes(mediaId))
);

if (mediaTag instanceof HTMLVideoElement) {
mediaTag.preload = 'metadata';
}

if (originalMediaId) {
// We now have the Original Rendition's ID
// Use that to update the `src` attribute to use Newshub's Web API
imageSourcesUpdated = true;
imageTag.src = `/assets/${originalMediaId}`;
mediaTag.src = `/assets/${originalMediaId}`;
}
});

Expand Down
2 changes: 1 addition & 1 deletion assets/ui/components/ArticleMedia.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default function ArticleMedia({isKilled, media, download}) {
<div className='wire-column__preview__video'>
<span className='wire-column__preview__video-headline'>{media.headline || media.description_text}</span>
{media.type === 'video' && (
<video controls>
<video controls preload="metadata">
<source src={rendition.href} type={rendition.mimetype} />
{gettext('Your browser does not support playing video')}
</video>
Expand Down
31 changes: 19 additions & 12 deletions assets/wire/components/ItemDetails.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ import {isDisplayed, gettext, formatDate, formatTime} from 'utils';
import ListItemPreviousVersions from './ListItemPreviousVersions';
import ListItemNextVersion from './ListItemNextVersion';
import {
getItemMedia,
getFeatureMedia,
getOtherMedia,
showItemVersions,
isKilled,
DISPLAY_ABSTRACT,
isPreformatted,
isCustomRendition,
getPictureList,
} from 'wire/utils';
import types from 'wire/types';
import Content from 'ui/components/Content';
Expand Down Expand Up @@ -48,8 +48,8 @@ function ItemDetails({
listConfig,
filterGroupLabels,
}) {
const pictures = getPictureList(item);
const media = getItemMedia(item);
const featureMedia = getFeatureMedia(item);
const media = getOtherMedia(item);
const itemType = isPreformatted(item) ? 'preformatted' : 'text';

return (
Expand All @@ -67,14 +67,21 @@ function ItemDetails({
</ContentHeader>
<ArticleItemDetails disableTextSelection={detailsConfig.disable_text_selection}>
<ArticleContent>
{pictures && pictures.map((pic) => (
<ArticlePicture
key={pic._id}
picture={pic}
isKilled={isKilled(item)}
isCustomRendition={isCustomRendition(pic)}
/>
))}
{featureMedia == null ? null : (
featureMedia.type === 'picture' ? (
<ArticlePicture
picture={featureMedia}
isKilled={isKilled(item)}
isCustomRendition={isCustomRendition(featureMedia)}
/>
) : (
<ArticleMedia
media={featureMedia}
isKilled={isKilled(item)}
download={downloadMedia}
/>
)
)}
<ArticleContentWrapper itemType={itemType}>
<ArticleBody itemType={itemType}>
<ArticleEmbargoed item={item} />
Expand Down
8 changes: 1 addition & 7 deletions assets/wire/components/PreviewMeta.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
import {getPicture, getVideos} from 'wire/utils';
import {FieldComponents} from './fields';
import WireListItemIcons from './WireListItemIcons';

Expand All @@ -19,16 +18,11 @@ function PreviewMeta({
listConfig,
filterGroupLabels,
}) {
const picture = getPicture(item);
const fields = displayConfig.metadata_fields || DEFAULT_META_FIELDS;

return (
<div className="wire-articles__item__meta">
<WireListItemIcons
item={item}
videos={getVideos(item)}
picture={picture}
/>
<WireListItemIcons item={item} />
<div className="wire-articles__item__meta-info">
<FieldComponents
config={fields}
Expand Down
31 changes: 7 additions & 24 deletions assets/wire/components/WireListItem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,10 @@ import {
getConfig,
} from 'utils';
import {
getPicture,
getThumbnailRendition,
getImageForList,
showItemVersions,
shortText,
isKilled,
getVideos,
getCaption,
} from 'wire/utils';

Expand Down Expand Up @@ -140,8 +138,7 @@ class WireListItem extends React.Component {
'wire-articles__item-select-visible': !LIST_ANIMATIONS,
'wire-articles__item-select': LIST_ANIMATIONS,
});
const picture = getPicture(item);
const videos = getVideos(item);
const listImage = getImageForList(item);
const isMarketPlace = this.props.context === 'aapX';
const fields = listConfig.metadata_fields || DEFAULT_META_FIELDS;
const compactFields = listConfig.compact_metadata_fields || DEFAULT_COMPACT_META_FIELDS;
Expand Down Expand Up @@ -179,8 +176,6 @@ class WireListItem extends React.Component {
{!isExtended && (
<WireListItemIcons
item={item}
picture={picture}
videos={videos}
divider={false}
/>
)}
Expand All @@ -192,11 +187,7 @@ class WireListItem extends React.Component {

{isExtended && !isMarketPlace && (
<div className="wire-articles__item__meta">
<WireListItemIcons
item={item}
picture={picture}
videos={videos}
/>
<WireListItemIcons item={item} />
<div className="wire-articles__item__meta-info">
<span className="bold">
{getSlugline(item, true)}
Expand Down Expand Up @@ -230,11 +221,7 @@ class WireListItem extends React.Component {
key="meta"
className="wire-articles__item__meta"
>
<WireListItemIcons
item={item}
picture={picture}
videos={videos}
/>
<WireListItemIcons item={item} />
<div className="wire-articles__item__meta-info">
<span>
{this.wordCount} {gettext('words')}
Expand Down Expand Up @@ -290,16 +277,12 @@ class WireListItem extends React.Component {
)}
</div>

{isExtended &&
!isKilled(item) &&
getThumbnailRendition(picture) && (
{isExtended && !isKilled(item) && listImage != null && (
<div className="wire-articles__item-image">
<figure>
<img
src={
getThumbnailRendition(picture).href
}
alt={getCaption(picture)}
src={listImage.href}
alt={getCaption(listImage.item)}
/>
</figure>
</div>
Expand Down
Loading

0 comments on commit a0dfbc6

Please sign in to comment.