web: common: init MediaViewer

This commit is contained in:
NikolayRechkin 2020-04-19 23:06:17 +03:00
parent 61762afb13
commit 1820a6a828
8 changed files with 263 additions and 2 deletions

View File

@ -32,8 +32,11 @@
"lodash-es": "4.17.15",
"moment": "^2.24.0",
"react-onclickoutside": "^6.9.0",
"react-player": "^1.15.3",
"react-svg": "^11.0.9",
"react-window-infinite-loader": "^1.0.5"
"react-viewer": "^3.2.1",
"react-window-infinite-loader": "^1.0.5",
"screenfull": "^5.0.2"
},
"devDependencies": {
"@babel/cli": "^7.8.3",

View File

@ -0,0 +1,42 @@
import React from "react";
import PropTypes from "prop-types";
import ImageViewer from "./sub-components/image-viewer"
import VideoViewer from "./sub-components/video-viewer"
class MediaViewer extends React.Component {
constructor(props) {
super(props);
this.state = {
visible: false,
};
}
render(){
return(
<div>
<button onClick={() => { this.setState({ visible: !this.state.visible }); } }>show</button>
<VideoViewer />
{/*
<ImageViewer
visible={this.state.visible}
onClose={() => { this.setState({ visible: false }); } }
images={[
{src: '', alt: ''},
{src: '', alt: ''}
]}
/>
*/}
</div>
)
};
}
MediaViewer.propTypes = {}
MediaViewer.defaultProps = {}
export default MediaViewer;

View File

@ -0,0 +1,17 @@
import React from 'react';
import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import Section from '../../../.storybook/decorators/section';
import MediaViewer from '.';
import withReadme from 'storybook-readme/with-readme';
import { withKnobs, boolean, text } from '@storybook/addon-knobs/react';
import Readme from './README.md';
storiesOf('Components|MediaViewer', module)
.addDecorator(withKnobs)
.addDecorator(withReadme(Readme))
.add('base', () => (
<Section>
<MediaViewer />
</Section>
));

View File

@ -0,0 +1,19 @@
# MediaViewer
### Usage
```js
import { MediaViewer } from "asc-web-common";
```
```jsx
<MediaViewer />
```
### Properties
| Props | Type | Required | Values | Default | Description |
| ------------- | :------------: | :------: | :----: | :-----: | --------------------------------------- |

View File

@ -0,0 +1 @@
export default from "./MediaViewer";

View File

@ -0,0 +1,24 @@
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

@ -0,0 +1,154 @@
import React from "react";
import PropTypes from "prop-types";
import Viewer from 'react-viewer';
import { Icons } from "asc-web-components";
import styled from "styled-components";
const StyledViewer = styled(Viewer)`
.react-viewer-attribute{
display: none;
}
.react-viewer-toolbar li{
width: 40px;
border-radius: 2px;
cursor: pointer;
line-height: 24px;
}
.react-viewer-btn{
background-color: none;
&:hover{
background-color: rgba(200, 200, 200, 0.2);
}
}
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;
}
}
`
const NextButton = styled.div`
height: 40px;
background-color: rgba(11, 11, 11, 0.7);
border-radius: 50%;
&:hover{
background-color: rgba(200, 200, 200, 0.2);
}
&:before{
content:'';
top: 12px;
left: ${props => props.orientation == "left" ? '9px;' : '15px;'};
position: absolute;
border: solid #fff;
border-width: 0 2px 2px 0;
display: inline-block;
padding: 7px;
transform: ${props => props.orientation == "left" ? 'rotate(-45deg)' : 'rotate(135deg)'};
-webkit-transform: ${props => props.orientation == "left" ? 'rotate(-45deg)' : 'rotate(135deg)'};
}
`;
const MediaScrollButton = props => {
//console.log("Backdrop render");
return (
<NextButton {...props} />
);
}
var customToolbar = [
{
key: 'zoomIn',
actionType: 1,
render: <Icons.PlusIcon size="medium" isfill={true} color="#fff" />
},
{
key: 'zoomOut',
actionType: 2,
render: <Icons.CrossIcon size="medium" isfill={true} color="#fff"/>
},
{
key: 'reset',
actionType: 7,
render: <Icons.AccessFormIcon size="medium" isfill={true} color="#fff"/>
},
{
key: 'rotateLeft',
actionType: 5,
render: <Icons.RotateIcon size="medium" isfill={true} color="#fff"/>
},
{
key: 'rotateRight',
actionType: 6,
render: <Icons.RotateIcon size="medium" isfill={true} color="#fff"/>
},
{
key: 'prev',
actionType: 3,
render: <MediaScrollButton orientation = "right" />
},
{
key: 'next',
actionType: 4,
render: <MediaScrollButton orientation = "left"/>
},
];
class ImageViewer extends React.Component {
constructor(props) {
super(props);
this.state = {
visible: false,
};
}
render(){
const { className, visible, onClose, images } = this.props;
return(
<div>
<StyledViewer
visible={visible}
onClose={onClose}
customToolbar={(toolbars) => {
return customToolbar;
}}
images={images}
/>
</div>
)
};
}
ImageViewer.propTypes = {}
ImageViewer.defaultProps = {}
export default ImageViewer;

View File

@ -11,4 +11,5 @@ export { default as PageLayout } from './PageLayout';
export { default as Layout } from './Layout';
export { default as ProfileMenu } from './ProfileMenu';
export { default as ErrorContainer } from './ErrorContainer';
export { default as ErrorBoundary } from './ErrorBoundary';
export { default as ErrorBoundary } from './ErrorBoundary';
export { default as MediaViewer } from './MediaViewer';