diff options
-rw-r--r-- | web/react/components/file_attachment.jsx | 101 | ||||
-rw-r--r-- | web/react/components/view_image.jsx | 45 | ||||
-rw-r--r-- | web/react/utils/utils.jsx | 2 | ||||
-rw-r--r-- | web/sass-files/sass/partials/_files.scss | 15 | ||||
-rw-r--r-- | web/sass-files/sass/partials/_modal.scss | 4 |
5 files changed, 123 insertions, 44 deletions
diff --git a/web/react/components/file_attachment.jsx b/web/react/components/file_attachment.jsx index afd4e32fe..a88731ca9 100644 --- a/web/react/components/file_attachment.jsx +++ b/web/react/components/file_attachment.jsx @@ -11,6 +11,8 @@ export default class FileAttachment extends React.Component { this.loadFiles = this.loadFiles.bind(this); this.playGif = this.playGif.bind(this); + this.stopGif = this.stopGif.bind(this); + this.addBackgroundImage = this.addBackgroundImage.bind(this); this.canSetState = false; this.state = {fileSize: -1, mime: '', playing: false, loading: false}; @@ -29,15 +31,9 @@ export default class FileAttachment extends React.Component { var filename = this.props.filename; if (filename) { - var fileInfo = utils.splitFileLocation(filename); + var fileInfo = this.getFileInfoFromName(filename); var type = utils.getFileType(fileInfo.ext); - // This is a temporary patch to fix issue with old files using absolute paths - if (fileInfo.path.indexOf('/api/v1/files/get') !== -1) { - fileInfo.path = fileInfo.path.split('/api/v1/files/get')[1]; - } - fileInfo.path = utils.getWindowLocationOrigin() + '/api/v1/files/get' + fileInfo.path; - if (type === 'image') { var self = this; // Need this reference since we use the given "this" $('<img/>').attr('src', fileInfo.path + '_thumb.jpg').load(function loadWrapper(path, name) { @@ -59,11 +55,7 @@ export default class FileAttachment extends React.Component { $(imgDiv).addClass('normal'); } - var re1 = new RegExp(' ', 'g'); - var re2 = new RegExp('\\(', 'g'); - var re3 = new RegExp('\\)', 'g'); - var url = path.replace(re1, '%20').replace(re2, '%28').replace(re3, '%29'); - $(imgDiv).css('background-image', 'url(' + url + '_thumb.jpg)'); + self.addBackgroundImage(name, path); } }; }(fileInfo.path, filename)); @@ -111,6 +103,39 @@ export default class FileAttachment extends React.Component { e.stopPropagation(); } + stopGif(e, filename) { + this.setState({playing: false}); + this.addBackgroundImage(filename); + e.stopPropagation(); + } + getFileInfoFromName(name) { + var fileInfo = utils.splitFileLocation(name); + + // This is a temporary patch to fix issue with old files using absolute paths + if (fileInfo.path.indexOf('/api/v1/files/get') !== -1) { + fileInfo.path = fileInfo.path.split('/api/v1/files/get')[1]; + } + fileInfo.path = utils.getWindowLocationOrigin() + '/api/v1/files/get' + fileInfo.path; + + return fileInfo; + } + addBackgroundImage(name, path) { + var fileUrl = path; + + if (name in this.refs) { + if (!path) { + fileUrl = this.getFileInfoFromName(name).path; + } + + var imgDiv = ReactDOM.findDOMNode(this.refs[name]); + var re1 = new RegExp(' ', 'g'); + var re2 = new RegExp('\\(', 'g'); + var re3 = new RegExp('\\)', 'g'); + var url = fileUrl.replace(re1, '%20').replace(re2, '%28').replace(re3, '%29'); + + $(imgDiv).css('background-image', 'url(' + url + '_thumb.jpg)'); + } + } removeBackgroundImage(name) { if (name in this.refs) { $(ReactDOM.findDOMNode(this.refs[name])).css('background-image', 'initial'); @@ -123,13 +148,13 @@ export default class FileAttachment extends React.Component { var fileUrl = utils.getFileUrl(filename); var type = utils.getFileType(fileInfo.ext); - var playButton = ''; + var playbackControls = ''; var loadedFile = ''; var loadingIndicator = ''; if (this.state.mime === 'image/gif') { - playButton = ( + playbackControls = ( <div - className='file-play-button' + className='file-playback-controls play' onClick={(e) => this.playGif(e, filename)} > {"►"} @@ -143,7 +168,14 @@ export default class FileAttachment extends React.Component { src={fileUrl} /> ); - playButton = ''; + playbackControls = ( + <div + className='file-playback-controls stop' + onClick={(e) => this.stopGif(e, filename)} + > + {"◼"} + </div> + ); } if (this.state.loading) { loadingIndicator = ( @@ -152,22 +184,35 @@ export default class FileAttachment extends React.Component { src='/static/images/load.gif' /> ); - playButton = ''; + playbackControls = ''; } var thumbnail; if (type === 'image') { - thumbnail = ( - <div - ref={filename} - className='post__load' - style={{backgroundImage: 'url(/static/images/load.gif)'}} - > - {loadingIndicator} - {playButton} - {loadedFile} - </div> - ); + if (this.state.playing) { + thumbnail = ( + <div + ref={filename} + className='post__load' + style={{backgroundImage: 'url(/static/images/load.gif)'}} + > + {playbackControls} + {loadedFile} + </div> + ); + } else { + thumbnail = ( + <div + ref={filename} + className='post__load' + style={{backgroundImage: 'url(/static/images/load.gif)'}} + > + {loadingIndicator} + {playbackControls} + {loadedFile} + </div> + ); + } } else { thumbnail = <div className={'file-icon ' + utils.getIconClassName(type)}/>; } diff --git a/web/react/components/view_image.jsx b/web/react/components/view_image.jsx index c8356b2fa..fbe32cb07 100644 --- a/web/react/components/view_image.jsx +++ b/web/react/components/view_image.jsx @@ -147,6 +147,14 @@ export default class ViewImageModal extends React.Component { e.stopPropagation(); e.preventDefault(); } + stopGif(e, filename) { + var isPlaying = this.state.isPlaying; + delete isPlaying[filename]; + this.setState({isPlaying}); + + e.stopPropagation(); + e.preventDefault(); + } componentDidMount() { $(window).on('keyup', this.handleKeyPress); @@ -179,7 +187,7 @@ export default class ViewImageModal extends React.Component { var fileType = Utils.getFileType(fileInfo.ext); if (fileType === 'image') { - if (typeof this.state.isPlaying[filename] !== 'undefined') { + if (filename in this.state.isPlaying) { return this.state.isPlaying[filename]; } @@ -232,16 +240,27 @@ export default class ViewImageModal extends React.Component { ); } - var playButton = ''; - if (this.state.fileMimes[filename] === 'image/gif' && !(filename in this.state.isLoading) && !(filename in this.state.isPlaying)) { - playButton = ( - <div - className='file-play-button' - onClick={(e) => this.playGif(e, filename, fileUrl)} - > - {"►"} - </div> - ); + var playbackControls = ''; + if (this.state.fileMimes[filename] === 'image/gif' && !(filename in this.state.isLoading)) { + if (filename in this.state.isPlaying) { + playbackControls = ( + <div + className='file-playback-controls stop' + onClick={(e) => this.stopGif(e, filename)} + > + {"◼"} + </div> + ); + } else { + playbackControls = ( + <div + className='file-playback-controls play' + onClick={(e) => this.playGif(e, filename, fileUrl)} + > + {"►"} + </div> + ); + } } var loadingIndicator = ''; @@ -252,7 +271,7 @@ export default class ViewImageModal extends React.Component { src='/static/images/load.gif' /> ); - playButton = ''; + playbackControls = ''; } // image files just show a preview of the file @@ -262,7 +281,7 @@ export default class ViewImageModal extends React.Component { target='_blank' > {loadingIndicator} - {playButton} + {playbackControls} <img style={{maxHeight: this.state.imgHeight}} ref='image' diff --git a/web/react/utils/utils.jsx b/web/react/utils/utils.jsx index 69c026271..b9084b26e 100644 --- a/web/react/utils/utils.jsx +++ b/web/react/utils/utils.jsx @@ -544,7 +544,7 @@ export function applyTheme(theme) { if (theme.buttonBg) { changeCss('.btn.btn-primary', 'background:' + theme.buttonBg, 1); changeCss('.btn.btn-primary:hover, .btn.btn-primary:active, .btn.btn-primary:focus', 'background:' + changeColor(theme.buttonBg, -0.25), 1); - changeCss('.file-play-button', 'color:' + changeColor(theme.buttonBg, -0.25), 1); + changeCss('.file-playback-controls', 'color:' + changeColor(theme.buttonBg, -0.25), 1); } if (theme.buttonColor) { diff --git a/web/sass-files/sass/partials/_files.scss b/web/sass-files/sass/partials/_files.scss index cb9ff6862..e4d658230 100644 --- a/web/sass-files/sass/partials/_files.scss +++ b/web/sass-files/sass/partials/_files.scss @@ -153,6 +153,9 @@ height: 100px; max-width: initial; } + &:hover .file-playback-controls.stop { + @include opacity(1); + } } .post-image__thumbnail { float: left; @@ -230,11 +233,19 @@ } } -.file-play-button { +.file-playback-controls { position: absolute; - right: 0; + right: 5px; bottom: 0; font-size: 22px; cursor: pointer; z-index: 2; + -webkit-transition: opacity 0.6s; + -moz-transition: opacity 0.6s; + -o-transition: opacity 0.6s; + transition: opacity 0.6s; + + &.stop { + @include opacity(0); + } } diff --git a/web/sass-files/sass/partials/_modal.scss b/web/sass-files/sass/partials/_modal.scss index 5a8c1899a..1dcdbf348 100644 --- a/web/sass-files/sass/partials/_modal.scss +++ b/web/sass-files/sass/partials/_modal.scss @@ -229,6 +229,10 @@ display: table-cell; vertical-align: middle; position: relative; + + &:hover .file-playback-controls.stop { + @include opacity(1); + } } img { max-width: 100%; |