summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Lu <david.lu@hotmail.com>2016-05-05 19:23:15 -0400
committerJoram Wilander <jwawilander@gmail.com>2016-05-05 19:23:15 -0400
commite89868630128499dfaa68a9cb132d1814da7ea8d (patch)
treef3b3ef0c9b79eb222984405986c692e7bba9590b
parentf2e788f4b12517759e016a9f48633597bed82e8f (diff)
downloadchat-e89868630128499dfaa68a9cb132d1814da7ea8d.tar.gz
chat-e89868630128499dfaa68a9cb132d1814da7ea8d.tar.bz2
chat-e89868630128499dfaa68a9cb132d1814da7ea8d.zip
[PLT-2802] Memory leaks in file upload shortcuts (#2889)
* Added file upload shortcuts (CTRL+U and CMD+U) * Added KeyCode for U * Preventing memory leaks
-rw-r--r--webapp/components/file_upload.jsx181
1 files changed, 93 insertions, 88 deletions
diff --git a/webapp/components/file_upload.jsx b/webapp/components/file_upload.jsx
index 8e631ac95..1201948d8 100644
--- a/webapp/components/file_upload.jsx
+++ b/webapp/components/file_upload.jsx
@@ -129,9 +129,7 @@ class FileUpload extends React.Component {
}
componentDidMount() {
- var inputDiv = ReactDOM.findDOMNode(this.refs.input);
var self = this;
- const {formatMessage} = this.props.intl;
if (this.props.postType === 'post') {
$('.row.main').dragster({
@@ -177,109 +175,116 @@ class FileUpload extends React.Component {
});
}
- document.addEventListener('paste', (e) => {
- if (!e.clipboardData) {
- return;
- }
+ document.addEventListener('paste', this.pasteUpload);
+ document.addEventListener('keydown', this.keyUpload);
+ }
- var textarea = $(inputDiv.parentNode.parentNode).find('.custom-textarea')[0];
+ componentWillUnmount() {
+ let target;
+ if (this.props.postType === 'post') {
+ target = $('.row.main');
+ } else {
+ target = $('.post-right__container');
+ }
- if (textarea !== e.target && !$.contains(textarea, e.target)) {
- return;
- }
+ document.removeEventListener('paste', this.pasteUpload);
+ document.removeEventListener('keydown', this.keyUpload);
- self.props.onUploadError(null);
+ // jquery-dragster doesn't provide a function to unregister itself so do it manually
+ target.off('dragenter dragleave dragover drop dragster:enter dragster:leave dragster:over dragster:drop');
+ }
- // This looks redundant, but must be done this way due to
- // setState being an asynchronous call
- var items = e.clipboardData.items;
- var numItems = 0;
- if (items) {
- for (let i = 0; i < items.length; i++) {
- if (items[i].type.indexOf('image') !== -1) {
- var testExt = items[i].type.split('/')[1].toLowerCase();
+ pasteUpload(e) {
+ var inputDiv = ReactDOM.findDOMNode(this.refs.input);
+ const {formatMessage} = this.props.intl;
- if (Constants.IMAGE_TYPES.indexOf(testExt) < 0) {
- continue;
- }
+ if (!e.clipboardData) {
+ return;
+ }
- numItems++;
- }
- }
+ var textarea = $(inputDiv.parentNode.parentNode).find('.custom-textarea')[0];
- var numToUpload = Math.min(Constants.MAX_UPLOAD_FILES - self.props.getFileCount(ChannelStore.getCurrentId()), numItems);
+ if (textarea !== e.target && !$.contains(textarea, e.target)) {
+ return;
+ }
- if (numItems > numToUpload) {
- self.props.onUploadError(formatMessage(holders.limited, {count: Constants.MAX_UPLOAD_FILES}));
- }
+ self.props.onUploadError(null);
- for (var i = 0; i < items.length && i < numToUpload; i++) {
- if (items[i].type.indexOf('image') !== -1) {
- var file = items[i].getAsFile();
-
- var ext = items[i].type.split('/')[1].toLowerCase();
-
- if (Constants.IMAGE_TYPES.indexOf(ext) < 0) {
- continue;
- }
-
- var channelId = self.props.channelId || ChannelStore.getCurrentId();
-
- // generate a unique id that can be used by other components to refer back to this file upload
- var clientId = Utils.generateId();
-
- var d = new Date();
- var hour;
- if (d.getHours() < 10) {
- hour = '0' + d.getHours();
- } else {
- hour = String(d.getHours());
- }
- var min;
- if (d.getMinutes() < 10) {
- min = '0' + d.getMinutes();
- } else {
- min = String(d.getMinutes());
- }
-
- const name = formatMessage(holders.pasted) + d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate() + ' ' + hour + '-' + min + '.' + ext;
-
- const request = Client.uploadFile(file,
- name,
- channelId,
- clientId,
- self.fileUploadSuccess.bind(self, channelId),
- self.fileUploadFail.bind(self, clientId)
- );
-
- const requests = self.state.requests;
- requests[clientId] = request;
- self.setState({requests});
-
- self.props.onUploadStart([clientId], channelId);
+ // This looks redundant, but must be done this way due to
+ // setState being an asynchronous call
+ var items = e.clipboardData.items;
+ var numItems = 0;
+ if (items) {
+ for (let i = 0; i < items.length; i++) {
+ if (items[i].type.indexOf('image') !== -1) {
+ var testExt = items[i].type.split('/')[1].toLowerCase();
+
+ if (Constants.IMAGE_TYPES.indexOf(testExt) < 0) {
+ continue;
}
+
+ numItems++;
}
}
- });
- document.addEventListener('keydown', (e) => {
- //CTRL+U or CMD+U for file uploads
- if ((e.ctrlKey || e.metaKey) && e.keyCode === Constants.KeyCodes.U) {
- $(this.refs.input).focus().trigger('click');
+ var numToUpload = Math.min(Constants.MAX_UPLOAD_FILES - self.props.getFileCount(ChannelStore.getCurrentId()), numItems);
+
+ if (numItems > numToUpload) {
+ self.props.onUploadError(formatMessage(holders.limited, {count: Constants.MAX_UPLOAD_FILES}));
}
- });
- }
- componentWillUnmount() {
- let target;
- if (this.props.postType === 'post') {
- target = $('.row.main');
- } else {
- target = $('.post-right__container');
+ for (var i = 0; i < items.length && i < numToUpload; i++) {
+ if (items[i].type.indexOf('image') !== -1) {
+ var file = items[i].getAsFile();
+
+ var ext = items[i].type.split('/')[1].toLowerCase();
+
+ if (Constants.IMAGE_TYPES.indexOf(ext) < 0) {
+ continue;
+ }
+ var channelId = self.props.channelId || ChannelStore.getCurrentId();
+
+ // generate a unique id that can be used by other components to refer back to this file upload
+ var clientId = Utils.generateId();
+
+ var d = new Date();
+ var hour;
+ if (d.getHours() < 10) {
+ hour = '0' + d.getHours();
+ } else {
+ hour = String(d.getHours());
+ }
+ var min;
+ if (d.getMinutes() < 10) {
+ min = '0' + d.getMinutes();
+ } else {
+ min = String(d.getMinutes());
+ }
+
+ const name = formatMessage(holders.pasted) + d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate() + ' ' + hour + '-' + min + '.' + ext;
+
+ const request = Client.uploadFile(file,
+ name,
+ channelId,
+ clientId,
+ self.fileUploadSuccess.bind(self, channelId),
+ self.fileUploadFail.bind(self, clientId)
+ );
+
+ const requests = self.state.requests;
+ requests[clientId] = request;
+ self.setState({requests});
+
+ self.props.onUploadStart([clientId], channelId);
+ }
+ }
}
+ }
- // jquery-dragster doesn't provide a function to unregister itself so do it manually
- target.off('dragenter dragleave dragover drop dragster:enter dragster:leave dragster:over dragster:drop');
+ keyUpload(e) {
+ if ((e.ctrlKey || e.metaKey) && e.keyCode === Constants.KeyCodes.U) {
+ $(this.refs.input).focus().trigger('click');
+ }
}
cancelUpload(clientId) {