Skip to content

Commit 31c1b05

Browse files
leotollkevhender
andauthored
Fix Video component and add autoplay (#76)
* fix: Video component and add autplay * add sources support to video * Remove poster from video. * Version bump Co-authored-by: kevhender <[email protected]>
1 parent d960644 commit 31c1b05

File tree

5 files changed

+84
-23
lines changed

5 files changed

+84
-23
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-storefront",
3-
"version": "7.12.0",
3+
"version": "7.12.1",
44
"description": "Build and deploy e-commerce progressive web apps (PWAs) in record time.",
55
"module": "./index.js",
66
"license": "Apache-2.0",

src/carousel/Media.js

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@ const useStyles = makeStyles(theme => ({
2323
export default function Media({
2424
magnifyProps,
2525
imageProps,
26+
videoProps,
2627
src,
2728
alt,
2829
magnify,
30+
sources,
2931
poster,
3032
type = 'image',
3133
}) {
@@ -55,7 +57,17 @@ export default function Media({
5557
}
5658

5759
if (type === 'video') {
58-
return <video src={src} alt={alt} poster={poster} />
60+
if (sources && sources.length) {
61+
return (
62+
<video alt={alt} {...videoProps}>
63+
{sources.map(source => (
64+
<source key={source.src} src={source.src} type={source.type} />
65+
))}
66+
</video>
67+
)
68+
} else {
69+
return <video src={src} alt={alt} {...videoProps} />
70+
}
5971
} else if (magnify) {
6072
return (
6173
<ReactImageMagnify
@@ -86,6 +98,11 @@ Media.propTypes = {
8698
*/
8799
magnifyProps: PropTypes.object,
88100

101+
/**
102+
* Other props to pass to the video component.
103+
*/
104+
videoProps: PropTypes.object,
105+
89106
/**
90107
* Other props to pass to the [`Image`](/apiReference/Image) for an `'image'` type.
91108
*/
@@ -102,9 +119,9 @@ Media.propTypes = {
102119
src: PropTypes.string,
103120

104121
/**
105-
* Used as the `poster` attribute for a `<video>`.
122+
* Used as the source inside the video `<video>`.
106123
*/
107-
poster: PropTypes.string,
124+
sources: PropTypes.array,
108125

109126
/**
110127
* An object to pass to pass to `ReactImageMagnify` containing the data for the magnified image.

src/carousel/MediaCarousel.js

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ function MediaCarousel(props) {
131131
thumbsClassName,
132132
thumbnailPosition,
133133
magnifyHintClassName,
134+
videoProps,
134135
imageProps,
135136
lightboxProps,
136137
lightboxClassName,
@@ -149,6 +150,7 @@ function MediaCarousel(props) {
149150
const ref = useRef(null)
150151
const [over, setOver] = useState(false)
151152
const [selected, setSelected] = useState(0)
153+
const [video, setVideo] = useState(false)
152154
const [lightboxActive, setLightboxActive] = useState()
153155
const theme = useTheme()
154156
const isSmall = useMediaQuery(theme.breakpoints.down('xs'))
@@ -160,6 +162,14 @@ function MediaCarousel(props) {
160162
setSelected(0)
161163
}, [media])
162164

165+
useEffect(() => {
166+
if (media && media.full && media.full[selected].type === 'video') {
167+
setVideo(true)
168+
} else {
169+
setVideo(false)
170+
}
171+
}, [selected])
172+
163173
const timeout = useRef(null)
164174

165175
const handleMouseEnter = useCallback(() => {
@@ -182,7 +192,7 @@ function MediaCarousel(props) {
182192
}, [])
183193

184194
const onClickCarousel = useCallback(evt => {
185-
if (!evt.defaultPrevented) {
195+
if (!evt.defaultPrevented && !video) {
186196
setLightboxActive(true)
187197
}
188198
})
@@ -215,7 +225,7 @@ function MediaCarousel(props) {
215225
showHint = false
216226
}
217227
}
218-
if (showHint) {
228+
if (showHint && !video) {
219229
belowAdornments.push(
220230
<MagnifyHint
221231
key="magnify-hint"
@@ -280,8 +290,9 @@ function MediaCarousel(props) {
280290
contain: true,
281291
src: get(item, 'magnify.src', item.src),
282292
}
283-
: item.imageProps
293+
: imageProps
284294
}
295+
videoProps={videoProps}
285296
/>
286297
</Fill>
287298
))}
@@ -356,6 +367,10 @@ MediaCarousel.propTypes = {
356367
* An optional `className` to use for the [`MagnifyHint`](/apiReference/carousel/MagnifyHint) component.
357368
*/
358369
magnifyHintClassName: PropTypes.string,
370+
/**
371+
* Props passed through to each [`Media`](/apiReference/carousel/Media)'s video component.
372+
*/
373+
videoProps: PropTypes.object,
359374
/**
360375
* Props passed through to each [`Media`](/apiReference/carousel/Media)'s
361376
* [`imageProps`](/apiReference/carousel/Media#prop-imageProps).
@@ -402,6 +417,10 @@ MediaCarousel.defaultProps = {
402417
MediaComponent: Media,
403418
CarouselComponent: Carousel,
404419
CarouselThumbnailsComponent: CarouselThumbnails,
420+
videoProps: {
421+
controls: true,
422+
autoPlay: false,
423+
},
405424
}
406425

407426
export default React.memo(MediaCarousel)

test/carousel/Media.test.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ describe('Media', () => {
2525
expect(wrapper.find('video')).toExist()
2626
})
2727

28+
it('should render sources inside video if defined', () => {
29+
wrapper = mount(<Media type="video" sources={[{ src: 'test1' }]} />)
30+
31+
expect(wrapper.find('source')).toExist()
32+
})
33+
2834
it('should render ReactImageMagnify if magnify prop is passed', () => {
2935
wrapper = mount(
3036
<Media magnify={{ src: 'test', width: 1000, height: 1000 }} src="test" alt="test" />,

test/carousel/MediaCarousel.test.js

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,29 @@ jest.useFakeTimers()
1414

1515
describe('MediaCarousel', () => {
1616
let wrapper
17+
let media
1718

1819
const mockMediaQuery = jest.spyOn(useMediaQuery, 'default')
1920

2021
beforeEach(() => {
2122
window.innerWidth = 1024
2223
window.dispatchEvent(new Event('resize'))
24+
25+
media = {
26+
full: [1, 2, 3].map(key => ({
27+
src: `test${key}`,
28+
alt: `test${key}`,
29+
magnify: {
30+
height: 1200,
31+
width: 1200,
32+
src: `test${key}`,
33+
},
34+
})),
35+
thumbnails: [1, 2, 3].map(key => ({
36+
src: `testThumb${key}`,
37+
alt: `testThumb${key}`,
38+
})),
39+
}
2340
})
2441

2542
afterEach(() => {
@@ -34,22 +51,6 @@ describe('MediaCarousel', () => {
3451
jest.restoreAllMocks()
3552
})
3653

37-
const media = {
38-
full: [1, 2, 3].map(key => ({
39-
src: `test${key}`,
40-
alt: `test${key}`,
41-
magnify: {
42-
height: 1200,
43-
width: 1200,
44-
src: `test${key}`,
45-
},
46-
})),
47-
thumbnails: [1, 2, 3].map(key => ({
48-
src: `testThumb${key}`,
49-
alt: `testThumb${key}`,
50-
})),
51-
}
52-
5354
it('should have MagnifyHint and thumbnails when media has those', () => {
5455
wrapper = mount(<MediaCarousel media={media} />)
5556

@@ -85,6 +86,24 @@ describe('MediaCarousel', () => {
8586
expect(wrapper.find(Lightbox).prop('open')).toBe(true)
8687
})
8788

89+
it('should not open lightbox on MediaCarousel click if active media is video', () => {
90+
media.full[0].type = 'video'
91+
92+
wrapper = mount(<MediaCarousel media={media} />)
93+
94+
expect(wrapper.find(Lightbox).prop('open')).toBe(false)
95+
wrapper.find(Carousel).simulate('click')
96+
expect(wrapper.find(Lightbox).prop('open')).toBe(false)
97+
})
98+
99+
it('should not show MagnifyHint if active media is video', () => {
100+
media.full[0].type = 'video'
101+
102+
wrapper = mount(<MediaCarousel media={media} />)
103+
104+
expect(wrapper.find(MagnifyHint)).not.toExist()
105+
})
106+
88107
it('should not open lightbox on MediaCarousel click if event is default prevented', () => {
89108
wrapper = mount(<MediaCarousel media={media} />)
90109

0 commit comments

Comments
 (0)