diff options
author | Corey Hulen <corey@hulen.com> | 2015-09-24 08:59:00 -0700 |
---|---|---|
committer | Corey Hulen <corey@hulen.com> | 2015-09-24 08:59:00 -0700 |
commit | 819ef528b858f81f239406ed3a05f9170eee2c93 (patch) | |
tree | bc2e67a0e5364d36d22a681a5fbb56b008b15ce8 /web/react/components/view_image.jsx | |
parent | a7d75d3bceef5fa405e72968806c905bcc9d8b31 (diff) | |
parent | c5d78f828a48ba88b8a89a0564bcb8352e84b396 (diff) | |
download | chat-819ef528b858f81f239406ed3a05f9170eee2c93.tar.gz chat-819ef528b858f81f239406ed3a05f9170eee2c93.tar.bz2 chat-819ef528b858f81f239406ed3a05f9170eee2c93.zip |
Merge pull request #779 from mattermost/plt-294
PLT-294 Converting preview image modal to use react-bootstrap.
Diffstat (limited to 'web/react/components/view_image.jsx')
-rw-r--r-- | web/react/components/view_image.jsx | 232 |
1 files changed, 94 insertions, 138 deletions
diff --git a/web/react/components/view_image.jsx b/web/react/components/view_image.jsx index dafcdd9f9..8db63e196 100644 --- a/web/react/components/view_image.jsx +++ b/web/react/components/view_image.jsx @@ -3,6 +3,8 @@ var Client = require('../utils/client.jsx'); var Utils = require('../utils/utils.jsx'); +var ViewImagePopoverBar = require('./view_image_popover_bar.jsx'); +var Modal = ReactBootstrap.Modal; export default class ViewImageModal extends React.Component { constructor(props) { @@ -16,6 +18,10 @@ export default class ViewImageModal extends React.Component { this.handleKeyPress = this.handleKeyPress.bind(this); this.getPublicLink = this.getPublicLink.bind(this); this.getPreviewImagePath = this.getPreviewImagePath.bind(this); + this.onModalShown = this.onModalShown.bind(this); + this.onModalHidden = this.onModalHidden.bind(this); + this.onMouseEnterImage = this.onMouseEnterImage.bind(this); + this.onMouseLeaveImage = this.onMouseLeaveImage.bind(this); var loaded = []; var progress = []; @@ -23,9 +29,18 @@ export default class ViewImageModal extends React.Component { loaded.push(false); progress.push(0); } - this.state = {imgId: this.props.startId, viewed: false, loaded: loaded, progress: progress, images: {}, fileSizes: {}}; + this.state = { + imgId: this.props.startId, + imgHeight: '100%', + loaded: loaded, + progress: progress, + images: {}, + fileSizes: {}, + showFooter: false + }; } - handleNext() { + handleNext(e) { + e.stopPropagation(); var id = this.state.imgId + 1; if (id > this.props.filenames.length - 1) { id = 0; @@ -33,7 +48,8 @@ export default class ViewImageModal extends React.Component { this.setState({imgId: id}); this.loadImage(id); } - handlePrev() { + handlePrev(e) { + e.stopPropagation(); var id = this.state.imgId - 1; if (id < 0) { id = this.props.filenames.length - 1; @@ -50,15 +66,27 @@ export default class ViewImageModal extends React.Component { this.handlePrev(); } } - componentWillReceiveProps(nextProps) { + onModalShown(nextProps) { this.setState({imgId: nextProps.startId}); + this.loadImage(nextProps.startId); + } + onModalHidden() { + if (this.refs.video) { + var video = React.findDOMNode(this.refs.video); + video.pause(); + video.currentTime = 0; + } + } + componentWillReceiveProps(nextProps) { + if (nextProps.show === true && this.props.show === false) { + this.onModalShown(nextProps); + } else if (nextProps.show === false && this.props.show === true) { + this.onModalHidden(); + } } loadImage(id) { var imgHeight = $(window).height() - 100; - if (this.state.loaded[id] || this.state.images[id]) { - $('.modal .modal-image .image-wrapper img').css('max-height', imgHeight); - return; - } + this.setState({imgHeight}); var filename = this.props.filenames[id]; @@ -68,84 +96,27 @@ export default class ViewImageModal extends React.Component { if (fileType === 'image') { var img = new Image(); img.load(this.getPreviewImagePath(filename), - function load() { - var progress = this.state.progress; - progress[id] = img.completedPercentage; - this.setState({progress: progress}); - }.bind(this)); - img.onload = (function onload(imgid) { - return function onloadReturn() { - var loaded = this.state.loaded; - loaded[imgid] = true; - this.setState({loaded: loaded}); - $(React.findDOMNode(this.refs.image)).css('max-height', imgHeight); - }.bind(this); - }.bind(this)(id)); + () => { + const progress = this.state.progress; + progress[id] = img.completedPercentage; + this.setState({progress}); + }); + img.onload = () => { + const loaded = this.state.loaded; + loaded[id] = true; + this.setState({loaded}); + }; var images = this.state.images; images[id] = img; - this.setState({images: images}); + this.setState({images}); } else { // there's nothing to load for non-image files var loaded = this.state.loaded; loaded[id] = true; - this.setState({loaded: loaded}); - } - } - componentDidUpdate() { - if (this.state.loaded[this.state.imgId]) { - if (this.refs.imageWrap) { - $(React.findDOMNode(this.refs.imageWrap)).removeClass('default'); - } + this.setState({loaded}); } } componentDidMount() { - $('#' + this.props.modalId).on('shown.bs.modal', function onModalShow() { - this.setState({viewed: true}); - this.loadImage(this.state.imgId); - }.bind(this)); - - $('#' + this.props.modalId).on('hidden.bs.modal', function onModalHide() { - if (this.refs.video) { - var video = React.findDOMNode(this.refs.video); - video.pause(); - video.currentTime = 0; - } - }.bind(this)); - - $(React.findDOMNode(this.refs.modal)).click(function onModalClick(e) { - if (e.target === this || e.target === React.findDOMNode(this.refs.imageBody)) { - $('.image_modal').modal('hide'); - } - }.bind(this)); - - $(React.findDOMNode(this.refs.imageWrap)).hover( - function onModalHover() { - $(React.findDOMNode(this.refs.imageFooter)).addClass('footer--show'); - }.bind(this), function offModalHover() { - $(React.findDOMNode(this.refs.imageFooter)).removeClass('footer--show'); - }.bind(this) - ); - - if (this.refs.previewArrowLeft) { - $(React.findDOMNode(this.refs.previewArrowLeft)).hover( - function onModalHover() { - $(React.findDOMNode(this.refs.imageFooter)).addClass('footer--show'); - }.bind(this), function offModalHover() { - $(React.findDOMNode(this.refs.imageFooter)).removeClass('footer--show'); - }.bind(this) - ); - } - - if (this.refs.previewArrowRight) { - $(React.findDOMNode(this.refs.previewArrowRight)).hover( - function onModalHover() { - $(React.findDOMNode(this.refs.imageFooter)).addClass('footer--show'); - }.bind(this), function offModalHover() { - $(React.findDOMNode(this.refs.imageFooter)).removeClass('footer--show'); - }.bind(this) - ); - } - $(window).on('keyup', this.handleKeyPress); // keep track of whether or not this component is mounted so we can safely set the state asynchronously @@ -189,6 +160,12 @@ export default class ViewImageModal extends React.Component { // only images have proper previews, so just use a placeholder icon for non-images return Utils.getPreviewImagePathForFileType(fileType); } + onMouseEnterImage() { + this.setState({showFooter: true}); + } + onMouseLeaveImage() { + this.setState({showFooter: false}); + } render() { if (this.props.filenames.length < 1 || this.props.filenames.length - 1 < this.state.imgId) { return <div/>; @@ -299,23 +276,6 @@ export default class ViewImageModal extends React.Component { bgClass = 'black-bg'; } - var publicLink = ''; - if (global.window.config.EnablePublicLink === 'true') { - publicLink = ( - <div> - <a - href='#' - className='public-link text' - data-title='Public Image' - onClick={this.getPublicLink} - > - Get Public Link - </a> - <span className='text'> | </span> - </div> - ); - } - var leftArrow = ''; var rightArrow = ''; if (this.props.filenames.length > 1) { @@ -342,65 +302,61 @@ export default class ViewImageModal extends React.Component { ); } + let closeButtonClass = 'modal-close'; + if (this.state.showFooter) { + closeButtonClass += ' modal-close--show'; + } + return ( - <div - className='modal fade image_modal' - ref='modal' - id={this.props.modalId} - tabIndex='-1' - role='dialog' - aria-hidden='true' + <Modal + show={this.props.show} + onHide={this.props.onModalDismissed} + className='image_modal' + dialogClassName='modal-image' > - <div className='modal-dialog modal-image'> - <div className='modal-content image-content'> + <Modal.Body + modalClassName='image-body' + onClick={this.props.onModalDismissed} + > + <div + className={'image-wrapper ' + bgClass} + style={{maxHeight: this.state.imgHeight}} + onMouseEnter={this.onMouseEnterImage} + onMouseLeave={this.onMouseLeaveImage} + onClick={(e) => e.stopPropagation()} + > <div - ref='imageBody' - className='modal-body image-body' - > - <div - ref='imageWrap' - className={'image-wrapper default ' + bgClass} - > - <div - className='modal-close' - data-dismiss='modal' - /> - {content} - <div - ref='imageFooter' - className='modal-button-bar' - > - <span className='pull-left text'>{'File ' + (this.state.imgId + 1) + ' of ' + this.props.filenames.length}</span> - <div className='image-links'> - {publicLink} - <a - href={fileUrl} - download={name} - className='text' - > - Download - </a> - </div> - </div> - </div> - {leftArrow} - {rightArrow} - </div> + className={closeButtonClass} + onClick={this.props.onModalDismissed} + /> + {content} + <ViewImagePopoverBar + show={this.state.showFooter} + fileId={this.state.imgId} + totalFiles={this.props.filenames.length} + filename={name} + fileURL={fileUrl} + onGetPublicLinkPressed={this.getPublicLink} + /> </div> - </div> - </div> + {leftArrow} + {rightArrow} + </Modal.Body> + </Modal> ); } } ViewImageModal.defaultProps = { + show: false, filenames: [], - modalId: '', channelId: '', userId: '', startId: 0 }; ViewImageModal.propTypes = { + show: React.PropTypes.bool.isRequired, + onModalDismissed: React.PropTypes.func.isRequired, filenames: React.PropTypes.array, modalId: React.PropTypes.string, channelId: React.PropTypes.string, |