Skip to content

Commit

Permalink
fix: [Video] show the play button when the cover is specified
Browse files Browse the repository at this point in the history
  • Loading branch information
akai committed Jan 6, 2021
1 parent 3199031 commit 3d91644
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 37 deletions.
75 changes: 38 additions & 37 deletions src/components/Video/index.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,33 @@
import React, { useState, useRef, useEffect } from 'react';
import React, { useState, useRef } from 'react';
import clsx from 'clsx';

export interface VideoProps {
className?: string;
src: string;
src?: string;
cover?: string;
duration?: string | number;
style?: React.CSSProperties;
videoRef?: React.RefObject<HTMLVideoElement>;
onClick?: (paused: boolean, event: React.MouseEvent) => void;
onCoverLoad?: (event: React.SyntheticEvent) => void;
}

export const Video: React.FC<VideoProps> = (props) => {
const { className, src, cover, duration, onClick, onCoverLoad, style, ...other } = props;
const {
className,
src,
cover,
duration,
onClick,
onCoverLoad,
style,
videoRef = useRef<HTMLVideoElement>(null),
children,
...other
} = props;

const [isPlayed, setIsPlayed] = useState(false);
const [paused, setPaused] = useState(true);
const videoRef = useRef<HTMLVideoElement>(null);

function handleClick(e: React.MouseEvent) {
setIsPlayed(true);
Expand All @@ -34,52 +45,42 @@ export const Video: React.FC<VideoProps> = (props) => {
}
}

useEffect(() => {
const video = videoRef.current;
const handlePlay = () => {
setPaused(false);
};
const handlePause = () => {
setPaused(true);
};
function handlePlay() {
setPaused(false);
}

if (video) {
video.addEventListener('play', handlePlay);
video.addEventListener('pause', handlePause);
video.addEventListener('ended', handlePause);
}
function handlePause() {
setPaused(true);
}

return () => {
if (video) {
video.removeEventListener('play', handlePlay);
video.removeEventListener('pause', handlePause);
video.removeEventListener('ended', handlePause);
}
};
}, []);
const hasCover = !isPlayed && !!cover;
const hasDuration = hasCover && !!duration;

return (
<div
className={clsx('Video', `Video--${paused ? 'paused' : 'playing'}`, className)}
style={style}
>
{!isPlayed && (
<>
{cover && <img className="Video-cover" src={cover} onLoad={onCoverLoad} alt="" />}
{duration && <span className="Video-duration">{duration}</span>}
</>
)}
{hasCover && <img className="Video-cover" src={cover} onLoad={onCoverLoad} alt="" />}
{hasDuration && <span className="Video-duration">{duration}</span>}
<video
className="Video-video"
src={src}
ref={videoRef}
hidden={!!cover && !isPlayed}
hidden={hasCover}
controls
onPlay={handlePlay}
onPause={handlePause}
onEnded={handlePause}
{...other}
/>
<button className={clsx('Video-playBtn', { paused })} type="button" onClick={handleClick}>
<span className="Video-playIcon" />
</button>
>
{children}
</video>
{hasCover && (
<button className={clsx('Video-playBtn', { paused })} type="button" onClick={handleClick}>
<span className="Video-playIcon" />
</button>
)}
</div>
);
};
};
4 changes: 4 additions & 0 deletions src/components/Video/style.less
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
padding: 0;
border: 0;
background: transparent;

&:hover {
cursor: pointer;
}
}

.Video-playIcon {
Expand Down
21 changes: 21 additions & 0 deletions storybook/stories/Video.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';
import { Story, Meta } from '@storybook/react/types-6-0';

import { Video, VideoProps } from '../../src';
// import '../../src/components/Video/style.less';

export default {
title: 'Video',
component: Video,
} as Meta;

const Template: Story<VideoProps> = (args) => <Video {...args} />;

export const Default = Template.bind({});
Default.args = {
src: '//interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4',
alt: 'flower',
style: {
width: '320px'
}
};

0 comments on commit 3d91644

Please sign in to comment.