summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Orben <florian.orben@gmail.com>2015-10-19 22:30:00 +0200
committerFlorian Orben <florian.orben@gmail.com>2015-10-21 18:13:59 +0200
commitcd5df514c7d3130c9765a8160dfd31abccb8b741 (patch)
tree4d0f17c60ae95140d043a6bb36bd46bf559506e5
parent420c754ca300d6f089adc9f22d34a8acb00a571e (diff)
downloadchat-cd5df514c7d3130c9765a8160dfd31abccb8b741.tar.gz
chat-cd5df514c7d3130c9765a8160dfd31abccb8b741.tar.bz2
chat-cd5df514c7d3130c9765a8160dfd31abccb8b741.zip
Add stop button to stop animated gifs
-rw-r--r--web/react/components/file_attachment.jsx101
-rw-r--r--web/react/components/view_image.jsx45
-rw-r--r--web/react/utils/utils.jsx2
-rw-r--r--web/sass-files/sass/partials/_files.scss15
-rw-r--r--web/sass-files/sass/partials/_modal.scss4
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%;