caf5b8e975
before. In the API, attachments now can be either image, video or gifv. Gifv is to be treated like images in terms of behaviour, but are videos by file type.
170 lines
3.8 KiB
JavaScript
170 lines
3.8 KiB
JavaScript
import { connect } from 'react-redux';
|
|
import {
|
|
closeModal,
|
|
decreaseIndexInModal,
|
|
increaseIndexInModal
|
|
} from '../../../actions/modal';
|
|
import Lightbox from '../../../components/lightbox';
|
|
import ImageLoader from 'react-imageloader';
|
|
import LoadingIndicator from '../../../components/loading_indicator';
|
|
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
|
import ExtendedVideoPlayer from '../../../components/extended_video_player';
|
|
|
|
const mapStateToProps = state => ({
|
|
media: state.getIn(['modal', 'media']),
|
|
index: state.getIn(['modal', 'index']),
|
|
isVisible: state.getIn(['modal', 'open'])
|
|
});
|
|
|
|
const mapDispatchToProps = dispatch => ({
|
|
onCloseClicked () {
|
|
dispatch(closeModal());
|
|
},
|
|
|
|
onOverlayClicked () {
|
|
dispatch(closeModal());
|
|
},
|
|
|
|
onNextClicked () {
|
|
dispatch(increaseIndexInModal());
|
|
},
|
|
|
|
onPrevClicked () {
|
|
dispatch(decreaseIndexInModal());
|
|
}
|
|
});
|
|
|
|
const imageStyle = {
|
|
display: 'block',
|
|
maxWidth: '80vw',
|
|
maxHeight: '80vh'
|
|
};
|
|
|
|
const loadingStyle = {
|
|
width: '400px',
|
|
paddingBottom: '120px'
|
|
};
|
|
|
|
const preloader = () => (
|
|
<div className='modal-container--preloader' style={loadingStyle}>
|
|
<LoadingIndicator />
|
|
</div>
|
|
);
|
|
|
|
const leftNavStyle = {
|
|
position: 'absolute',
|
|
background: 'rgba(0, 0, 0, 0.5)',
|
|
padding: '30px 15px',
|
|
cursor: 'pointer',
|
|
fontSize: '24px',
|
|
top: '0',
|
|
left: '-61px',
|
|
boxSizing: 'border-box',
|
|
height: '100%',
|
|
display: 'flex',
|
|
alignItems: 'center'
|
|
};
|
|
|
|
const rightNavStyle = {
|
|
position: 'absolute',
|
|
background: 'rgba(0, 0, 0, 0.5)',
|
|
padding: '30px 15px',
|
|
cursor: 'pointer',
|
|
fontSize: '24px',
|
|
top: '0',
|
|
right: '-61px',
|
|
boxSizing: 'border-box',
|
|
height: '100%',
|
|
display: 'flex',
|
|
alignItems: 'center'
|
|
};
|
|
|
|
const Modal = React.createClass({
|
|
|
|
propTypes: {
|
|
media: ImmutablePropTypes.list,
|
|
index: React.PropTypes.number.isRequired,
|
|
isVisible: React.PropTypes.bool,
|
|
onCloseClicked: React.PropTypes.func,
|
|
onOverlayClicked: React.PropTypes.func,
|
|
onNextClicked: React.PropTypes.func,
|
|
onPrevClicked: React.PropTypes.func
|
|
},
|
|
|
|
mixins: [PureRenderMixin],
|
|
|
|
handleNextClick () {
|
|
this.props.onNextClicked();
|
|
},
|
|
|
|
handlePrevClick () {
|
|
this.props.onPrevClicked();
|
|
},
|
|
|
|
componentDidMount () {
|
|
this._listener = e => {
|
|
if (!this.props.isVisible) {
|
|
return;
|
|
}
|
|
|
|
switch(e.key) {
|
|
case 'ArrowLeft':
|
|
this.props.onPrevClicked();
|
|
break;
|
|
case 'ArrowRight':
|
|
this.props.onNextClicked();
|
|
break;
|
|
}
|
|
};
|
|
|
|
window.addEventListener('keyup', this._listener);
|
|
},
|
|
|
|
componentWillUnmount () {
|
|
window.removeEventListener('keyup', this._listener);
|
|
},
|
|
|
|
render () {
|
|
const { media, index, ...other } = this.props;
|
|
|
|
if (!media) {
|
|
return null;
|
|
}
|
|
|
|
const attachment = media.get(index);
|
|
const url = attachment.get('url');
|
|
|
|
let leftNav, rightNav, content;
|
|
|
|
leftNav = rightNav = content = '';
|
|
|
|
if (media.size > 1) {
|
|
leftNav = <div style={leftNavStyle} className='modal-container--nav' onClick={this.handlePrevClick}><i className='fa fa-fw fa-chevron-left' /></div>;
|
|
rightNav = <div style={rightNavStyle} className='modal-container--nav' onClick={this.handleNextClick}><i className='fa fa-fw fa-chevron-right' /></div>;
|
|
}
|
|
|
|
if (attachment.get('type') === 'image') {
|
|
content = (
|
|
<ImageLoader
|
|
src={url}
|
|
preloader={preloader}
|
|
imgProps={{ style: imageStyle }}
|
|
/>
|
|
);
|
|
} else if (attachment.get('type') === 'gifv') {
|
|
content = <ExtendedVideoPlayer src={url} />;
|
|
}
|
|
|
|
return (
|
|
<Lightbox {...other}>
|
|
{leftNav}
|
|
{content}
|
|
{rightNav}
|
|
</Lightbox>
|
|
);
|
|
}
|
|
|
|
});
|
|
|
|
export default connect(mapStateToProps, mapDispatchToProps)(Modal);
|