From 1e6fb33447786608bb4d1cc501a68d4a014f86fb Mon Sep 17 00:00:00 2001 From: Artur Gaspar Date: Tue, 17 Oct 2023 22:28:25 -0300 Subject: [PATCH] feat: video gallery thumbnail fallback --- src/editors/containers/VideoGallery/index.jsx | 16 +- .../SelectionModal/Gallery.jsx | 12 +- .../SelectionModal/GalleryCard.jsx | 131 +++++++++------- .../SelectionModal/GalleryCard.test.jsx | 10 ++ .../__snapshots__/GalleryCard.test.jsx.snap | 145 ++++++++++++++++++ 5 files changed, 254 insertions(+), 60 deletions(-) diff --git a/src/editors/containers/VideoGallery/index.jsx b/src/editors/containers/VideoGallery/index.jsx index 0600c1334..08e970d63 100644 --- a/src/editors/containers/VideoGallery/index.jsx +++ b/src/editors/containers/VideoGallery/index.jsx @@ -1,4 +1,5 @@ import React, { useEffect } from 'react'; +import { Image } from '@edx/paragon'; import { useSelector } from 'react-redux'; import { selectors } from '../../data/redux'; import hooks from './hooks'; @@ -6,6 +7,7 @@ import SelectionModal from '../../sharedComponents/SelectionModal'; import { acceptedImgKeys } from './utils'; import messages from './messages'; import { RequestKeys } from '../../data/constants/requests'; +import videoThumbnail from '../../data/images/videoThumbnail.svg'; export const VideoGallery = () => { const rawVideos = useSelector(selectors.app.videos); @@ -45,6 +47,15 @@ export const VideoGallery = () => { uploadError: messages.uploadVideoError, }; + const thumbnailFallback = ( + + ); + return ( { galleryError, inputError, fileInput, - galleryProps, + galleryProps: { + ...galleryProps, + thumbnailFallback, + }, searchSortProps, selectBtnProps, acceptedFiles: acceptedImgKeys, diff --git a/src/editors/sharedComponents/SelectionModal/Gallery.jsx b/src/editors/sharedComponents/SelectionModal/Gallery.jsx index 37e61e990..88a141144 100644 --- a/src/editors/sharedComponents/SelectionModal/Gallery.jsx +++ b/src/editors/sharedComponents/SelectionModal/Gallery.jsx @@ -23,6 +23,7 @@ export const Gallery = ({ showIdsOnCards, height, isLoaded, + thumbnailFallback, }) => { const intl = useIntl(); if (!isLoaded) { @@ -66,7 +67,14 @@ export const Gallery = ({ type="radio" value={highlighted} > - { displayList.map(asset => ) } + { displayList.map(asset => ( + + )) } @@ -78,6 +86,7 @@ Gallery.defaultProps = { showIdsOnCards: false, height: '375px', show: true, + thumbnailFallback: undefined, }; Gallery.propTypes = { show: PropTypes.bool, @@ -90,6 +99,7 @@ Gallery.propTypes = { emptyGalleryLabel: PropTypes.shape({}).isRequired, showIdsOnCards: PropTypes.bool, height: PropTypes.string, + thumbnailFallback: PropTypes.element, }; export default Gallery; diff --git a/src/editors/sharedComponents/SelectionModal/GalleryCard.jsx b/src/editors/sharedComponents/SelectionModal/GalleryCard.jsx index 0a8c75353..f4ddc6420 100644 --- a/src/editors/sharedComponents/SelectionModal/GalleryCard.jsx +++ b/src/editors/sharedComponents/SelectionModal/GalleryCard.jsx @@ -14,67 +14,81 @@ import LanguageNamesWidget from '../../containers/VideoEditor/components/VideoSe export const GalleryCard = ({ asset, -}) => ( - -
-
- - { asset.status && asset.statusBadgeVariant && ( - - {asset.status} - - )} - { asset.duration >= 0 && ( - - {formatDuration(asset.duration)} - - )} -
-
-

{asset.displayName}

- { asset.transcripts && ( -
- { + const [thumbnailError, setThumbnailError] = React.useState(false); + return ( + +
+
+ {(thumbnailError && thumbnailFallback) ? ( +
+ { thumbnailFallback } +
+ ) : ( + setThumbnailError(true))} + /> + )} + { asset.status && asset.statusBadgeVariant && ( + + {asset.status} + + )} + { asset.duration >= 0 && ( + + {formatDuration(asset.duration)} + + )} +
+
+

{asset.displayName}

+ { asset.transcripts && ( +
+ +
+ )} +

+ , + time: , + }} /> -

- )} -

- , - time: , - }} - /> -

+

+
-
- -); + + ); +}; +GalleryCard.defaultProps = { + thumbnailFallback: undefined, +}; GalleryCard.propTypes = { asset: PropTypes.shape({ contentType: PropTypes.string, @@ -91,6 +105,7 @@ GalleryCard.propTypes = { statusBadgeVariant: PropTypes.string, transcripts: PropTypes.arrayOf(PropTypes.string), }).isRequired, + thumbnailFallback: PropTypes.element, }; export default GalleryCard; diff --git a/src/editors/sharedComponents/SelectionModal/GalleryCard.test.jsx b/src/editors/sharedComponents/SelectionModal/GalleryCard.test.jsx index 5eb49456f..4b3ec843c 100644 --- a/src/editors/sharedComponents/SelectionModal/GalleryCard.test.jsx +++ b/src/editors/sharedComponents/SelectionModal/GalleryCard.test.jsx @@ -10,6 +10,7 @@ describe('GalleryCard component', () => { displayName: 'props.img.displayName', dateAdded: 12345, }; + const thumbnailFallback = (Image failed to load); let el; beforeEach(() => { el = shallow(); @@ -20,6 +21,15 @@ describe('GalleryCard component', () => { it('loads Image with src from image external url', () => { expect(el.find(Image).props().src).toEqual(asset.externalUrl); }); + it('snapshot with thumbnail fallback and load error', () => { + el = shallow(); + el.find(Image).props().onError(); + expect(el).toMatchSnapshot(); + }); + it('snapshot with thumbnail fallback and no error', () => { + el = shallow(); + expect(el).toMatchSnapshot(); + }); it('snapshot with status badge', () => { el = shallow(); expect(el).toMatchSnapshot(); diff --git a/src/editors/sharedComponents/SelectionModal/__snapshots__/GalleryCard.test.jsx.snap b/src/editors/sharedComponents/SelectionModal/__snapshots__/GalleryCard.test.jsx.snap index 769e70144..810913c68 100644 --- a/src/editors/sharedComponents/SelectionModal/__snapshots__/GalleryCard.test.jsx.snap +++ b/src/editors/sharedComponents/SelectionModal/__snapshots__/GalleryCard.test.jsx.snap @@ -253,6 +253,151 @@ exports[`GalleryCard component snapshot with status badge 1`] = ` `; +exports[`GalleryCard component snapshot with thumbnail fallback and load error 1`] = ` + +
+
+
+ + Image failed to load + +
+
+
+

+ props.img.displayName +

+

+ , + "time": , + } + } + /> +

+
+
+
+`; + +exports[`GalleryCard component snapshot with thumbnail fallback and no error 1`] = ` + +
+
+ +
+
+

+ props.img.displayName +

+

+ , + "time": , + } + } + /> +

+
+
+
+`; + exports[`GalleryCard component snapshot: dateAdded=12345 1`] = `