Web:Common:Components:MediaViewer:Sub-Components: Removed old unnecessary components

This commit is contained in:
Akmal Isomadinov 2023-02-18 23:37:37 +05:00
parent bcfef89ef1
commit e810217b42
4 changed files with 0 additions and 1156 deletions

View File

@ -1,24 +0,0 @@
import React from "react";
export default function Duration({ className, seconds }) {
return (
<time dateTime={`P${Math.round(seconds)}S`} className={className}>
{format(seconds)}
</time>
);
}
function format(seconds) {
const date = new Date(seconds * 1000);
const hh = date.getUTCHours();
const mm = date.getUTCMinutes();
const ss = pad(date.getUTCSeconds());
if (hh) {
return `${hh}:${pad(mm)}:${ss}`;
}
return `${mm}:${ss}`;
}
function pad(string) {
return ("0" + string).slice(-2);
}

View File

@ -1,415 +0,0 @@
import React from "react";
import PropTypes from "prop-types";
import styled from "styled-components";
import MediaZoomInIcon from "PUBLIC_DIR/images/media.zoomin.react.svg";
import MediaZoomOutIcon from "PUBLIC_DIR/images/media.zoomout.react.svg";
import MediaRotateLeftIcon from "PUBLIC_DIR/images/media.rotateleft.react.svg";
import MediaRotateRightIcon from "PUBLIC_DIR/images/media.rotateright.react.svg";
import MediaDeleteIcon from "PUBLIC_DIR/images/media.delete.react.svg";
import MediaDownloadIcon from "PUBLIC_DIR/images/download.react.svg";
import commonIconsStyles from "@docspace/components/utils/common-icons-style";
import MediaFavoriteIcon from "PUBLIC_DIR/images/favorite.react.svg";
import ViewerSeparator from "PUBLIC_DIR/images/viewer.separator.react.svg";
import MediaShare from "PUBLIC_DIR/images/share.react.svg";
import DropDownItem from "@docspace/components/drop-down-item";
import DropDown from "@docspace/components/drop-down";
import equal from "fast-deep-equal/react";
import { Base } from "@docspace/components/themes";
import { Viewer } from "@docspace/components/viewer";
const StyledViewer = styled(Viewer)`
.react-viewer-footer {
bottom: 5px !important;
z-index: 301 !important;
overflow: visible;
}
.react-viewer-canvas {
z-index: 300 !important;
margin-top: 50px;
}
.react-viewer-navbar,
.react-viewer-mask,
.react-viewer-attribute,
.react-viewer-close {
display: none;
}
.react-viewer-toolbar {
position: relative;
overflow: visible;
bottom: 4px;
}
.react-viewer-toolbar li {
width: 40px;
height: 30px;
margin-top: 4px;
border-radius: 2px;
cursor: pointer;
line-height: 24px;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
.react-viewer-btn {
background-color: transparent;
&:hover {
background-color: ${(props) =>
props.theme.mediaViewer.imageViewer.backgroundColor};
}
}
.react-viewer-image-transition {
transition-duration: 0s;
}
li[data-key="prev"] {
left: 20px;
}
li[data-key="next"] {
right: 20px;
}
li[data-key="prev"],
li[data-key="next"] {
position: fixed;
top: calc(50% - 20px);
height: auto;
background: none;
&:hover {
background: none;
}
}
li[data-key="delete"],
li[data-key="customDownload"] {
position: fixed;
@media (max-width: 600px) {
position: initial;
}
bottom: 9px;
.controlBtn {
margin: 0;
}
}
li[data-key="delete"] {
right: 62px;
}
li[data-key="customDownload"] {
right: 12px;
}
.iconContainer {
width: 24px;
height: 24px;
line-height: 20px;
margin: 3px auto;
&.reset {
width: 18px;
}
path,
rect {
fill: ${(props) => props.theme.mediaViewer.imageViewer.fill};
}
}
.btnContainer {
display: block;
width: 16px;
height: 16px;
margin: 4px 12px;
line-height: 19px;
path,
rect {
fill: ${(props) => props.theme.mediaViewer.imageViewer.fill};
}
}
.scrollBtn {
cursor: ${(props) => (props.inactive ? "default" : "pointer")};
opacity: ${(props) => (props.inactive ? "0.2" : "1")};
&:hover {
background-color: ${(props) =>
!props.inactive
? props.theme.mediaViewer.imageViewer.backgroundColor
: props.theme.mediaViewer.imageViewer.inactiveBackgroundColor};
}
}
`;
const StyledDropDown = styled(DropDown)`
background: #333;
`;
const StyledDropDownItem = styled(DropDownItem)`
color: #fff;
.drop-down-item_icon svg {
path {
fill: #fff !important;
}
}
/* .is-separator {
height: 1px;
background: #474747;
} */
&:hover {
background: #444;
}
`;
StyledViewer.defaultProps = { theme: Base };
class ImageViewer extends React.Component {
// componentDidUpdate() {
// document.getElementsByClassName("iconContainer reset").length > 0 &&
// document.getElementsByClassName("iconContainer reset")[0].click();
// }
shouldComponentUpdate(nextProps) {
return !equal(this.props, nextProps);
}
render() {
const {
className,
visible,
images,
inactive,
onClose,
userAccess,
title,
errorTitle,
onPrevClick,
onNextClick,
playlist,
playlistPos,
isImage,
isAudio,
isVideo,
isPreviewFile,
archiveRoom,
contextModel,
audioIcon,
headerIcon,
onSetSelectionFile,
onDownloadClick,
} = this.props;
const generateContextMenu = (isOpen, right, bottom) => {
const model = contextModel();
const onItemClick = (e, item) => {
const { action, onClick } = item;
return onClick({ originalEvent: e, action: action, item });
};
return (
<StyledDropDown
open={isOpen}
isDefaultMode={false}
directionY="top"
directionX="right"
fixedDirection={true}
withBackdrop={false}
manualY={(bottom || "63") + "px"}
manualX={(right || "-31") + "px"}
>
{model.map((item) => {
if (item.disabled) return;
const onClick = (e) => {
onClose();
onItemClick(e, item);
};
return (
<StyledDropDownItem
className={`${item.isSeparator ? "is-separator" : ""}`}
key={item.key}
label={item.label}
icon={item.icon ? item.icon : ""}
action={item.action}
onClick={onClick}
/>
);
})}
</StyledDropDown>
);
};
var customToolbar = [
{
key: "zoomOut",
percent: true,
actionType: 2,
render: (
<div className="iconContainer zoomOut">
<MediaZoomOutIcon size="scale" />
</div>
),
},
{
key: "percent",
actionType: 999,
},
{
key: "zoomIn",
actionType: 1,
render: (
<div className="iconContainer zoomIn">
<MediaZoomInIcon size="scale" />
</div>
),
},
{
key: "rotateLeft",
actionType: 5,
render: (
<div className="iconContainer rotateLeft">
<MediaRotateLeftIcon size="scale" />
</div>
),
},
{
key: "rotateRight",
actionType: 6,
render: (
<div className="iconContainer rotateRight">
<MediaRotateRightIcon size="scale" />
</div>
),
},
{
key: "separator download-separator",
actionType: -1,
noHover: true,
render: (
<div className="separator" style={{ height: "16px" }}>
<ViewerSeparator size="scale" />
</div>
),
},
// {
// key: "share",
// actionType: 101,
// render: (
// <div className="iconContainer share" style={{ height: "16px" }}>
// <MediaShare size="scale" />
// </div>
// ),
// },
{
key: "download",
actionType: 102,
render: (
<div className="iconContainer download" style={{ height: "16px" }}>
<MediaDownloadIcon size="scale" />
</div>
),
},
{
key: "context-separator",
actionType: -1,
noHover: true,
render: (
<div className="separator" style={{ height: "16px" }}>
<ViewerSeparator size="scale" />
</div>
),
},
{
key: "context-menu",
actionType: -1,
},
{
key: "delete",
actionType: 103,
render: (
<div className="iconContainer viewer-delete">
<MediaDeleteIcon size="scale" />
</div>
),
},
{
key: "favorite",
actionType: 104,
render: (
<div className="iconContainer viewer-favorite">
<MediaFavoriteIcon size="scale" />
</div>
),
},
];
customToolbar.forEach((button) => {
switch (button.key) {
case "prev":
button.onClick = this.props.onPrevClick;
break;
case "next":
button.onClick = this.props.onNextClick;
break;
case "delete":
button.onClick = this.props.onDeleteClick;
break;
case "download":
button.onClick = onDownloadClick;
break;
default:
break;
}
});
const canShare = playlist[playlistPos].canShare;
const toolbars =
!canShare && userAccess
? customToolbar.filter(
(x) => x.key !== "share" && x.key !== "share-separator"
)
: customToolbar.filter((x) => x.key !== "delete");
return (
<div className={className}>
<Viewer
inactive={inactive}
visible={visible}
zoomSpeed={0.25}
title={title}
errorTitle={errorTitle}
contextModel={contextModel}
generateContextMenu={generateContextMenu}
isImage={isImage}
headerIcon={headerIcon}
isAudio={isAudio}
isVideo={isVideo}
isPreviewFile={isPreviewFile}
archiveRoom={archiveRoom}
audioIcon={audioIcon}
onSetSelectionFile={onSetSelectionFile}
onMaskClick={onClose}
onNextClick={onNextClick}
onPrevClick={onPrevClick}
onDownloadClick={onDownloadClick}
playlist={playlist}
playlistPos={playlistPos}
customToolbar={() => toolbars}
images={images}
/>
</div>
);
}
}
ImageViewer.propTypes = {
className: PropTypes.string,
visible: PropTypes.bool,
inactive: PropTypes.bool,
images: PropTypes.arrayOf(PropTypes.object),
onNextClick: PropTypes.func,
onPrevClick: PropTypes.func,
onDeleteClick: PropTypes.func,
onDownloadClick: PropTypes.func,
onClose: PropTypes.func,
};
export default ImageViewer;

View File

@ -1,138 +0,0 @@
import React from "react";
import styled from "styled-components";
import PropTypes from "prop-types";
import { Base } from "@docspace/components/themes";
const StyledProgress = styled.div`
display: inline-block;
.slider-container {
display: inline-block;
border-radius: 2px;
position: relative;
width: ${(props) => props.width}px;
height: 6px;
background: ${(props) =>
props.theme.mediaViewer.progressBar.backgroundColor};
margin: 15px 0;
vertical-align: middle;
}
.fill {
cursor: pointer;
width: ${(props) => 100 * props.value}%;
position: absolute;
top: calc(50% - 3px);
height: 6px;
background: ${(props) => props.theme.mediaViewer.progressBar.background};
border-radius: 2px;
}
input[type="range"] {
display: block;
overflow: visible;
background: transparent;
width: ${(props) => props.width}px;
height: 6px;
outline: none;
margin: 0;
-webkit-appearance: none;
position: relative;
cursor: pointer;
}
input[type="range"]::-webkit-slider-thumb {
position: relative;
appearance: none;
box-sizing: content-box;
width: 12px;
height: 12px;
margin-top: -3px;
background: white;
border-radius: 50%;
cursor: pointer;
}
input[type="range"]::-moz-range-thumb {
position: relative;
appearance: none;
box-sizing: content-box;
width: 12px;
height: 12px;
background: white;
border-radius: 50%;
margin-top: -3px;
cursor: pointer;
}
input[type="range"]::-ms-thumb {
position: relative;
appearance: none;
box-sizing: content-box;
width: 12px;
height: 12px;
background: white;
border-radius: 50%;
margin-top: -3px;
cursor: pointer;
}
input[type="range"]::-webkit-slider-runnable-track {
margin: 12px 0;
height: 6px;
border-radius: 2px;
cursor: pointer;
-webkit-appearance: none;
text-align: right;
pointer-events: none;
}
input[type="range"]::-moz-range-track {
margin: 12px 0;
height: 6px;
border-radius: 2px;
cursor: pointer;
-webkit-appearance: none;
text-align: right;
pointer-events: none;
}
input[type="range"]::-ms-track {
border-color: transparent;
color: transparent;
margin: 12px 0;
height: 6px;
border-radius: 2px;
cursor: pointer;
-webkit-appearance: none;
text-align: right;
pointer-events: none;
}
`;
StyledProgress.defaultProps = { theme: Base };
const Progress = (props) => {
return (
<StyledProgress {...props}>
<div className="slider-container">
<div className="fill"></div>
<input
type="range"
min={0}
max={0.999999}
step="any"
value={props.value}
onMouseDown={props.handleSeekMouseDown}
onChange={(event) => props.handleSeekChange(event)}
onMouseUp={props.handleSeekMouseUp}
/>
</div>
</StyledProgress>
);
};
Progress.propTypes = {
value: PropTypes.number,
handleSeekMouseDown: PropTypes.func,
handleSeekChange: PropTypes.func,
handleSeekMouseUp: PropTypes.func,
};
export default Progress;

View File

@ -1,579 +0,0 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
import styled, { css } from "styled-components";
import { findDOMNode } from "react-dom";
import screenfull from "screenfull";
import ReactPlayer from "react-player";
import Duration from "./duration";
import Progress from "./progress";
import MediaPauseIcon from "PUBLIC_DIR/images/media.pause.react.svg";
import MediaPlayIcon from "PUBLIC_DIR/images/media.play.react.svg";
import MediaFullScreenIcon from "PUBLIC_DIR/images/media.fullscreen.video.react.svg";
import MediaMuteIcon from "PUBLIC_DIR/images/media.mute.react.svg";
import MediaMuteOffIcon from "PUBLIC_DIR/images/media.muteoff.react.svg";
import commonIconsStyles from "@docspace/components/utils/common-icons-style";
import { Base } from "@docspace/components/themes";
const iconsStyles = css`
path,
stroke,
rect {
fill: ${(props) => props.theme.mediaViewer.videoViewer.fill};
}
`;
const controlsHeight = 40;
const StyledControls = styled.div`
height: ${(props) => props.height}px;
display: block;
position: fixed;
z-index: 301;
${(props) =>
!props.isVideo &&
`background-color: ${props.theme.mediaViewer.videoViewer.backgroundColor};`}
top: calc(50% + ${(props) => props.top}px);
left: ${(props) => props.left}px;
`;
StyledControls.defaultProps = { theme: Base };
const StyledVideoControlBtn = styled.div`
display: inline-block;
height: 26px;
line-height: 30px;
margin: 5px 2px;
width: 38px;
border-radius: 2px;
cursor: pointer;
text-align: center;
vertical-align: top;
&:hover {
background-color: ${(props) =>
props.theme.mediaViewer.videoViewer.background};
}
.playBtnContainer {
width: 16px;
height: 16px;
line-height: 0;
margin: 5px auto;
}
.pauseBtnContainer {
display: block;
width: 16px;
height: 16px;
margin: 3px 10px;
line-height: 19px;
}
.muteBtnContainer {
display: block;
width: 16px;
height: 16px;
margin: 3px 11px;
line-height: 19px;
}
.fullscreenBtnContainer {
display: block;
width: 16px;
height: 16px;
margin: 3px 11px;
line-height: 19px;
}
`;
StyledVideoControlBtn.defaultProps = { theme: Base };
const StyledMediaPauseIcon = styled(MediaPauseIcon)`
${commonIconsStyles}
${iconsStyles}
`;
StyledMediaPauseIcon.defaultProps = { theme: Base };
const StyledMediaPlayIcon = styled(MediaPlayIcon)`
${commonIconsStyles}
${iconsStyles}
`;
StyledMediaPlayIcon.defaultProps = { theme: Base };
const StyledMediaFullScreenIcon = styled(MediaFullScreenIcon)`
${commonIconsStyles}
${iconsStyles}
`;
StyledMediaFullScreenIcon.defaultProps = { theme: Base };
const StyledMediaMuteIcon = styled(MediaMuteIcon)`
${commonIconsStyles}
path:first-child {
stroke: ${(props) => props.theme.mediaViewer.videoViewer.stroke};
}
path:last-child {
fill: ${(props) => props.theme.mediaViewer.videoViewer.fill};
}
`;
const StyledMediaMuteOffIcon = styled(MediaMuteOffIcon)`
${commonIconsStyles}
path, rect {
fill: ${(props) => props.theme.mediaViewer.videoViewer.fill};
}
`;
StyledMediaMuteIcon.defaultProps = { theme: Base };
const VideoControlBtn = (props) => {
return (
<StyledVideoControlBtn {...props}>{props.children}</StyledVideoControlBtn>
);
};
VideoControlBtn.propTypes = {
children: PropTypes.any,
};
const Controls = (props) => {
return <StyledControls {...props}>{props.children}</StyledControls>;
};
Controls.propTypes = {
children: PropTypes.any,
};
const PlayBtn = (props) => {
return (
<VideoControlBtn onClick={props.onClick}>
{props.playing ? (
<div className="pauseBtnContainer">
<StyledMediaPauseIcon size="scale" />
</div>
) : (
<div className="playBtnContainer">
<StyledMediaPlayIcon size="scale" />
</div>
)}
</VideoControlBtn>
);
};
PlayBtn.propTypes = {
playing: PropTypes.bool,
onClick: PropTypes.func,
};
const FullScreenBtn = (props) => {
return (
<VideoControlBtn onClick={props.onClick}>
<div className="fullscreenBtnContainer">
<StyledMediaFullScreenIcon size="scale" />
</div>
</VideoControlBtn>
);
};
FullScreenBtn.propTypes = {
onClick: PropTypes.func,
};
const StyledValumeContainer = styled.div`
display: inline-block;
vertical-align: top;
line-height: 39px;
position: relative;
.muteConteiner {
display: none;
position: absolute;
width: 40px;
height: 80px;
border-radius: 5px;
top: -76px;
left: 5px;
background: black;
}
&:hover {
.muteConteiner {
display: inline-block;
}
}
.mute {
display: inline-block;
transform: rotate(-90deg);
margin: 22px -14px;
}
`;
const StyledDuration = styled.div`
display: inline-block;
height: 26px;
line-height: 26px;
margin: 5px;
width: 60px;
text-align: center;
vertical-align: top;
border-radius: 2px;
cursor: pointer;
&:hover {
background-color: ${(props) =>
props.theme.mediaViewer.videoViewer.background};
}
`;
StyledValumeContainer.defaultProps = { theme: Base };
const StyledVideoViewer = styled.div`
color: ${(props) => props.theme.mediaViewer.videoViewer.color};
.playerWrapper {
display: ${(props) => (props.isVideo ? "block" : "none")};
width: ${(props) => props.width}px;
height: ${(props) => props.height}px;
left: ${(props) => props.left}px;
top: calc(50% - ${(props) => props.top / 2}px);
z-index: 301;
position: fixed;
padding-bottom: 40px;
background-color: ${(props) =>
props.theme.mediaViewer.videoViewer.backgroundColor};
video {
z-index: 300;
}
}
`;
StyledVideoViewer.defaultProps = { theme: Base };
const ErrorContainer = styled.div`
z-index: 301;
display: block;
position: fixed;
left: calc(50% - 110px);
top: calc(50% - 40px);
background-color: ${(props) =>
props.theme.mediaViewer.videoViewer.backgroundColorError};
color: ${(props) => props.theme.mediaViewer.videoViewer.colorError};
border-radius: 10px;
padding: 20px;
text-align: center;
`;
ErrorContainer.defaultProps = { theme: Base };
class ValumeBtn extends Component {
constructor(props) {
super(props);
}
render() {
return (
<StyledValumeContainer>
<div className="muteConteiner">
<Progress
className="mute"
width={this.props.width}
value={this.props.volume}
onMouseDown={this.props.onMouseDown}
handleSeekChange={this.props.onChange}
onMouseUp={this.props.handleSeekMouseUp}
/>
</div>
<VideoControlBtn onClick={this.props.onChangeMute}>
<div className="muteBtnContainer">
{this.props.muted ? (
<StyledMediaMuteOffIcon size="scale" />
) : (
<StyledMediaMuteIcon size="scale" />
)}
</div>
</VideoControlBtn>
</StyledValumeContainer>
);
}
}
ValumeBtn.propTypes = {
width: PropTypes.number,
volume: PropTypes.number,
muted: PropTypes.bool,
onMouseDown: PropTypes.func,
onChange: PropTypes.func,
handleSeekMouseUp: PropTypes.func,
onChangeMute: PropTypes.func,
};
class VideoViewer extends Component {
state = {
url: this.props.url,
pip: false,
playing: false,
controls: false,
light: false,
volume: 0.3,
muted: false,
played: 0,
loaded: 0,
duration: 0,
playbackRate: 1.0,
loop: false,
isNew: false,
error: false,
isLoaded: false,
};
componentDidMount() {
document.addEventListener("keydown", this.onKeydown, false);
}
componentWillUnmount() {
document.removeEventListener("keydown", this.onKeydown, false);
}
componentDidUpdate(prevProps) {
if (this.props.url !== prevProps.url) {
this.setState({
url: this.props.url,
isNew: true,
error: false,
});
}
}
onKeydown = (e) => {
if (e.keyCode === 32) this.handlePlayPause();
};
handlePlayPause = () => {
this.setState({ playing: !this.state.playing, isNew: false });
};
handleStop = () => {
this.setState({ url: null, playing: false });
};
handleVolumeChange = (e) => {
this.setState({
volume: parseFloat(e.target.value),
muted: false,
});
};
handleToggleMuted = () => {
this.setState({ muted: !this.state.muted });
};
handlePlay = () => {
this.setState({ playing: true });
};
handleEnablePIP = () => {
this.setState({ pip: true });
};
handleDisablePIP = () => {
this.setState({ pip: false });
};
handlePause = () => {
this.setState({ playing: false });
};
handleSeekMouseDown = (e) => {
this.setState({ seeking: true });
};
handleSeekChange = (e) => {
this.setState({ played: parseFloat(e.target.value) });
};
handleSeekMouseUp = (e) => {
console.log(!isNaN(parseFloat(e.target.value)), parseFloat(e.target.value));
if (!isNaN(parseFloat(e.target.value))) {
this.setState({ seeking: false });
this.player.seekTo(parseFloat(e.target.value));
}
};
handleProgress = (state) => {
if (!this.state.seeking) {
this.setState(state);
}
};
handleEnded = () => {
this.setState({ playing: this.state.loop });
};
handleDuration = (duration) => {
this.setState({ duration });
};
handleClickFullscreen = () => {
screenfull.request(findDOMNode(this.player));
};
ref = (player) => {
this.player = player;
};
resizePlayer = (videoSize, screenSize) => {
var ratio = videoSize.h / videoSize.w;
if (videoSize.h > screenSize.h) {
videoSize.h = screenSize.h;
videoSize.w = videoSize.h / ratio;
}
if (videoSize.w > screenSize.w) {
videoSize.w = screenSize.w;
videoSize.h = videoSize.w * ratio;
}
return {
width: videoSize.w,
height: videoSize.h,
};
};
onError = (e) => {
console.log("onError", e);
this.setState({ error: true });
};
onPlay = () => {
this.setState({ playing: !this.state.isNew, isNew: false, isLoaded: true });
};
render() {
const {
url,
playing,
controls,
light,
volume,
muted,
loop,
played,
loaded,
duration,
playbackRate,
pip,
error,
isLoaded,
} = this.state;
const { errorLabel } = this.props;
const parentOffset = this.props.getOffset() || 0;
var screenSize = {
w: window.innerWidth,
h: window.innerHeight,
};
screenSize.h -= parentOffset + controlsHeight;
let width = screenSize.w;
let height = screenSize.h;
let centerAreaOx = screenSize.w / 2 + document.documentElement.scrollLeft;
let centerAreaOy = screenSize.h / 2 + document.documentElement.scrollTop;
let videoElement = document.getElementsByTagName("video")[0];
if (videoElement) {
width = this.props.isVideo
? videoElement.videoWidth || 480
: screenSize.w - 150;
height = this.props.isVideo ? videoElement.videoHeight || 270 : 0;
let resize = this.resizePlayer(
{
w: width,
h: height,
},
screenSize
);
width = resize.width;
height = resize.height;
}
let left = this.props.isVideo
? centerAreaOx - width / 2
: centerAreaOx - width / 2;
const videoControlBtnWidth = 220;
const audioControlBtnWidth = 170;
let progressWidth = this.props.isVideo
? width - videoControlBtnWidth
: width - audioControlBtnWidth;
if (error) {
return (
<ErrorContainer>
<p>{errorLabel}</p>
</ErrorContainer>
);
}
return (
<StyledVideoViewer
isVideo={this.props.isVideo}
width={width}
height={height}
left={left}
top={height + controlsHeight}
>
<div>
<div className="playerWrapper" onClick={this.handlePlayPause}>
<ReactPlayer
ref={this.ref}
className="react-player"
style={{ opacity: isLoaded ? 1 : 0 }}
width="100%"
height="100%"
url={url}
pip={pip}
playing={playing}
playsinline={true}
controls={controls}
light={light}
loop={loop}
playbackRate={playbackRate}
volume={volume}
muted={muted}
onPlay={this.onPlay}
onEnablePIP={this.handleEnablePIP}
onDisablePIP={this.handleDisablePIP}
onPause={this.handlePause}
onEnded={this.handleEnded}
onError={this.onError}
onProgress={this.handleProgress}
onDuration={this.handleDuration}
/>
</div>
<Controls
height={controlsHeight}
left={left}
top={height / 2 - controlsHeight / 2}
isVideo={this.props.isVideo}
>
<PlayBtn onClick={this.handlePlayPause} playing={playing} />
<Progress
value={played}
width={progressWidth}
onMouseDown={this.handleSeekMouseDown}
handleSeekChange={this.handleSeekChange}
onMouseUp={this.handleSeekMouseUp}
onTouchEnd={this.handleSeekMouseUp}
/>
<StyledDuration>
-<Duration seconds={duration * (1 - played)} />
</StyledDuration>
<ValumeBtn
width={64}
muted={muted}
volume={muted ? 0 : volume}
onChangeMute={this.handleToggleMuted}
onChange={this.handleVolumeChange}
/>
{this.props.isVideo && (
<FullScreenBtn onClick={this.handleClickFullscreen} />
)}
</Controls>
</div>
</StyledVideoViewer>
);
}
}
VideoViewer.propTypes = {
isVideo: PropTypes.bool,
url: PropTypes.string,
getOffset: PropTypes.func,
errorLabel: PropTypes.string,
};
export default VideoViewer;