diff options
Diffstat (limited to 'web/react/components')
-rw-r--r-- | web/react/components/create_comment.jsx | 4 | ||||
-rw-r--r-- | web/react/components/create_post.jsx | 4 | ||||
-rw-r--r-- | web/react/components/file_upload.jsx | 96 | ||||
-rw-r--r-- | web/react/components/post_list.jsx | 18 | ||||
-rw-r--r-- | web/react/components/post_right.jsx | 6 |
5 files changed, 118 insertions, 10 deletions
diff --git a/web/react/components/create_comment.jsx b/web/react/components/create_comment.jsx index 78e06c532..c954229ae 100644 --- a/web/react/components/create_comment.jsx +++ b/web/react/components/create_comment.jsx @@ -222,7 +222,9 @@ module.exports = React.createClass({ getFileCount={this.getFileCount} onUploadStart={this.handleUploadStart} onFileUpload={this.handleFileUploadComplete} - onUploadError={this.handleUploadError} /> + onUploadError={this.handleUploadError} + postType='comment' + channelId={this.props.channelId} /> </div> <MsgTyping channelId={this.props.channelId} parentId={this.props.rootId} /> <div className={postFooterClassName}> diff --git a/web/react/components/create_post.jsx b/web/react/components/create_post.jsx index 9ca1d5388..137420440 100644 --- a/web/react/components/create_post.jsx +++ b/web/react/components/create_post.jsx @@ -262,7 +262,9 @@ module.exports = React.createClass({ getFileCount={this.getFileCount} onUploadStart={this.handleUploadStart} onFileUpload={this.handleFileUploadComplete} - onUploadError={this.handleUploadError} /> + onUploadError={this.handleUploadError} + postType='post' + channelId='' /> </div> <div className={postFooterClassName}> {postError} diff --git a/web/react/components/file_upload.jsx b/web/react/components/file_upload.jsx index c1fab669c..f1a06c361 100644 --- a/web/react/components/file_upload.jsx +++ b/web/react/components/file_upload.jsx @@ -21,7 +21,7 @@ module.exports = React.createClass({ var element = $(this.refs.fileInput.getDOMNode()); var files = element.prop('files'); - var channelId = ChannelStore.getCurrentId(); + var channelId = this.props.channelId || ChannelStore.getCurrentId(); this.props.onUploadError(null); @@ -87,10 +87,101 @@ module.exports = React.createClass({ } } catch(e) {} }, + handleDrop: function(e) { + this.props.onUploadError(null); + + var files = e.originalEvent.dataTransfer.files; + if (!files.length) { + files = e.originalEvent.dataTransfer.getData('URL'); + } + var channelId = this.props.channelId || ChannelStore.getCurrentId(); + + if (typeof files !== 'string' && files.length) { + var numFiles = files.length; + + var numToUpload = Math.min(Constants.MAX_UPLOAD_FILES - this.props.getFileCount(channelId), numFiles); + + if (numFiles > numToUpload) { + this.props.onUploadError('Uploads limited to ' + Constants.MAX_UPLOAD_FILES + ' files maximum. Please use additional posts for more files.'); + } + + for (var i = 0; i < files.length && i < numToUpload; i++) { + if (files[i].size > Constants.MAX_FILE_SIZE) { + this.props.onUploadError('Files must be no more than ' + Constants.MAX_FILE_SIZE / 1000000 + ' MB'); + continue; + } + + // generate a unique id that can be used by other components to refer back to this file upload + var clientId = utils.generateId(); + + // Prepare data to be uploaded. + var formData = new FormData(); + formData.append('channel_id', channelId); + formData.append('files', files[i], files[i].name); + formData.append('client_ids', clientId); + + var request = client.uploadFile(formData, + function(data) { + var parsedData = $.parseJSON(data); + this.props.onFileUpload(parsedData['filenames'], parsedData['client_ids'], channelId); + + var requests = this.state.requests; + for (var i = 0; i < parsedData['client_ids'].length; i++) { + delete requests[parsedData['client_ids'][i]]; + } + this.setState({requests: requests}); + }.bind(this), + function(err) { + this.props.onUploadError(err, clientId); + }.bind(this) + ); + + var requests = this.state.requests; + requests[clientId] = request; + this.setState({requests: requests}); + + this.props.onUploadStart([clientId], channelId); + } + } + }, componentDidMount: function() { var inputDiv = this.refs.input.getDOMNode(); var self = this; + if (this.props.postType === 'post') { + $('.app__content').dragster({ + enter: function(dragsterEvent, e) { + $('.center-file-overlay').removeClass('invisible'); + $('.center-file-overlay').addClass('visible'); + }, + leave: function(dragsterEvent, e) { + $('.center-file-overlay').removeClass('visible'); + $('.center-file-overlay').addClass('invisible'); + }, + drop: function(dragsterEvent, e) { + $('.center-file-overlay').removeClass('visible'); + $('.center-file-overlay').addClass('invisible'); + self.handleDrop(e); + } + }); + } else if (this.props.postType === 'comment') { + $('.post-right__container').dragster({ + enter: function(dragsterEvent, e) { + $('.right-file-overlay').removeClass('invisible'); + $('.right-file-overlay').addClass('visible'); + }, + leave: function(dragsterEvent, e) { + $('.right-file-overlay').removeClass('visible'); + $('.right-file-overlay').addClass('invisible'); + }, + drop: function(dragsterEvent, e) { + $('.right-file-overlay').removeClass('visible'); + $('.right-file-overlay').addClass('invisible'); + self.handleDrop(e); + } + }); + } + document.addEventListener('paste', function(e) { var textarea = $(inputDiv.parentNode.parentNode).find('.custom-textarea')[0]; @@ -133,14 +224,13 @@ module.exports = React.createClass({ continue; } - var channelId = ChannelStore.getCurrentId(); + var channelId = this.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 formData = new FormData(); formData.append('channel_id', channelId); - var d = new Date(); var hour; if (d.getHours() < 10) { diff --git a/web/react/components/post_list.jsx b/web/react/components/post_list.jsx index 83f806b79..53e8d0761 100644 --- a/web/react/components/post_list.jsx +++ b/web/react/components/post_list.jsx @@ -463,11 +463,19 @@ module.exports = React.createClass({ } return ( - <div ref="postlist" className="post-list-holder-by-time"> - <div className="post-list__table"> - <div className="post-list__content"> - { more_messages } - { postCtls } + <div> + <div className='center-file-overlay invisible'> + <div> + <i className="fa fa-upload"></i> + <span>Drop a file to upload it.</span> + </div> + </div> + <div ref="postlist" className="post-list-holder-by-time"> + <div className="post-list__table"> + <div className="post-list__content"> + { more_messages } + { postCtls } + </div> </div> </div> </div> diff --git a/web/react/components/post_right.jsx b/web/react/components/post_right.jsx index ad8b54012..b772c7ee8 100644 --- a/web/react/components/post_right.jsx +++ b/web/react/components/post_right.jsx @@ -296,6 +296,12 @@ module.exports = React.createClass({ return ( <div className="post-right__container"> + <div className='center-file-overlay right-file-overlay invisible'> + <div> + <i className="fa fa-upload"></i> + <span>Drop a file to upload it.</span> + </div> + </div> <div className="search-bar__container sidebar--right__search-header">{searchForm}</div> <div className="sidebar-right__body"> <RhsHeaderPost fromSearch={this.props.fromSearch} isMentionSearch={this.props.isMentionSearch} /> |