DocSpace-buildtools/packages/components/viewer/index.js

182 lines
4.7 KiB
JavaScript

import * as React from "react";
import * as ReactDOM from "react-dom";
import {
StyledViewer,
StyledViewerContainer,
StyledNextToolbar,
StyledButtonScroll,
} from "./styled-viewer";
import ControlBtn from "./sub-components/control-btn";
import Text from "@docspace/components/text";
import IconButton from "@docspace/components/icon-button";
import { isMobileOnly } from "react-device-detect";
import MediaNextIcon from "../../../public/images/media.view.react.svg";
import MediaPrevIcon from "../../../public/images/media.viewer.prev.react.svg";
import ViewerPlayer from "./sub-components/viewer-player";
import MediaContextMenu from "../../../public/images/vertical-dots.react.svg";
import ContextMenu from "@docspace/components/context-menu";
import BackArrow from "../../../public/images/arrow.path.react.svg";
export const Viewer = (props) => {
const {
visible,
onMaskClick,
title,
onNextClick,
onPrevClick,
playlistPos,
playlist,
isImage,
contextModel,
generateContextMenu,
} = props;
const defaultContainer = React.useRef(
typeof document !== "undefined" ? document.createElement("div") : null
);
const [container, setContainer] = React.useState(props.container);
const [init, setInit] = React.useState(false);
const detailsContainerRef = React.useRef(null);
const viewerToolboxRef = React.useRef(null);
const videoElement = React.useRef(null);
const cm = React.useRef(null);
const [isFullscreen, setIsFullScreen] = React.useState(false);
React.useEffect(() => {
document.body.appendChild(defaultContainer.current);
}, []);
React.useEffect(() => {
if (props.visible && !init) {
setInit(true);
}
}, [props.visible, init]);
React.useEffect(() => {
if (props.container) {
setContainer(props.container);
} else {
setContainer(defaultContainer.current);
}
}, [props.container]);
if (!init) {
return null;
}
const onContextMenu = (e) => {
cm.current.show(e);
};
let detailsStyle = {
"z-index": "307",
position: "fixed",
top: "0",
left: "0",
right: "0",
height: "53px",
background: "#333",
display: "flex",
"justify-content": "space-around",
"align-items": "center",
};
const mobileDetails = (
<div className="mobile-details" style={detailsStyle}>
<BackArrow onClick={onMaskClick} />
<Text isBold fontSize="14px" color={"#D1D1D1"} className="title">
{title}
</Text>
<div className="details-context">
<MediaContextMenu onClick={onContextMenu} />
<ContextMenu
getContextModel={contextModel}
ref={cm}
withBackdrop={true}
/>
</div>
</div>
);
const viewerPortal = ReactDOM.createPortal(
<StyledViewer
{...props}
mobileDetails={mobileDetails}
generateContextMenu={generateContextMenu}
/>,
container
);
const videoPortal = ReactDOM.createPortal(
<ViewerPlayer
contextModel={contextModel}
mobileDetails={mobileDetails}
title={title}
onMaskClick={onMaskClick}
generateContextMenu={generateContextMenu}
setIsFullScreen={setIsFullScreen}
videoRef={videoElement}
video={playlist[playlistPos]}
activeIndex={playlistPos}
/>,
container
);
return (
<StyledViewerContainer visible={visible}>
{!isFullscreen && !isMobileOnly && (
<div>
<div className="details" ref={detailsContainerRef}>
<Text isBold fontSize="14px" className="title">
{title}
</Text>
<ControlBtn
onClick={onMaskClick && onMaskClick}
className="mediaPlayerClose"
>
<IconButton
color={"#fff"}
iconName="/static/images/cross.react.svg"
size={17}
isClickable
/>
</ControlBtn>
</div>
</div>
)}
{playlist.length > 1 && !isFullscreen && (
<>
<StyledNextToolbar left onClick={onPrevClick}>
<StyledButtonScroll orientation="left">
<MediaPrevIcon />
</StyledButtonScroll>
</StyledNextToolbar>
{playlistPos < playlist.length - 1 && (
<>
<StyledNextToolbar onClick={onNextClick}>
<StyledButtonScroll orientation="right">
<MediaNextIcon />
</StyledButtonScroll>
</StyledNextToolbar>
</>
)}
</>
)}
{isImage ? (
<>
<div className="mediaViewerToolbox" ref={viewerToolboxRef}></div>
{viewerPortal}
</>
) : (
<>{videoPortal}</>
)}
</StyledViewerContainer>
);
};