web: common: init MediaViewer
This commit is contained in:
parent
61762afb13
commit
1820a6a828
@ -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",
|
||||
|
42
web/ASC.Web.Common/src/components/MediaViewer/MediaViewer.js
Normal file
42
web/ASC.Web.Common/src/components/MediaViewer/MediaViewer.js
Normal 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;
|
@ -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>
|
||||
));
|
19
web/ASC.Web.Common/src/components/MediaViewer/README.md
Normal file
19
web/ASC.Web.Common/src/components/MediaViewer/README.md
Normal file
@ -0,0 +1,19 @@
|
||||
# MediaViewer
|
||||
|
||||
|
||||
|
||||
### Usage
|
||||
|
||||
```js
|
||||
import { MediaViewer } from "asc-web-common";
|
||||
```
|
||||
|
||||
```jsx
|
||||
<MediaViewer />
|
||||
```
|
||||
|
||||
### Properties
|
||||
|
||||
| Props | Type | Required | Values | Default | Description |
|
||||
| ------------- | :------------: | :------: | :----: | :-----: | --------------------------------------- |
|
||||
|
1
web/ASC.Web.Common/src/components/MediaViewer/index.js
Normal file
1
web/ASC.Web.Common/src/components/MediaViewer/index.js
Normal file
@ -0,0 +1 @@
|
||||
export default from "./MediaViewer";
|
@ -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)
|
||||
}
|
@ -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;
|
@ -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';
|
Loading…
Reference in New Issue
Block a user