diff options
Diffstat (limited to 'web/react/components/create_comment.jsx')
-rw-r--r-- | web/react/components/create_comment.jsx | 217 |
1 files changed, 109 insertions, 108 deletions
diff --git a/web/react/components/create_comment.jsx b/web/react/components/create_comment.jsx index 88c01c586..78e06c532 100644 --- a/web/react/components/create_comment.jsx +++ b/web/react/components/create_comment.jsx @@ -18,20 +18,24 @@ module.exports = React.createClass({ handleSubmit: function(e) { e.preventDefault(); - if (this.state.uploadsInProgress > 0) return; + if (this.state.uploadsInProgress.length > 0) { + return; + } - if (this.state.submitting) return; + if (this.state.submitting) { + return; + } - var post = {} + var post = {}; post.filenames = []; - post.message = this.state.messageText; + if (post.message.trim().length === 0 && this.state.previews.length === 0) { return; } if (post.message.length > Constants.CHARACTER_LIMIT) { - this.setState({ post_error: 'Comment length must be less than '+Constants.CHARACTER_LIMIT+' characters.' }); + this.setState({postError: 'Comment length must be less than ' + Constants.CHARACTER_LIMIT + ' characters.'}); return; } @@ -40,163 +44,154 @@ module.exports = React.createClass({ post.parent_id = this.props.parentId; post.filenames = this.state.previews; - this.setState({ submitting: true, limit_error: null }); + this.setState({submitting: true, serverError: null}); client.createPost(post, ChannelStore.getCurrent(), function(data) { PostStore.storeCommentDraft(this.props.rootId, null); - this.setState({ messageText: '', submitting: false, post_error: null, server_error: null }); + this.setState({messageText: '', submitting: false, postError: null, serverError: null}); this.clearPreviews(); AsyncClient.getPosts(true, this.props.channelId); var channel = ChannelStore.get(this.props.channelId); var member = ChannelStore.getMember(this.props.channelId); member.msg_count = channel.total_msg_count; - member.last_viewed_at = (new Date).getTime(); + member.last_viewed_at = Date.now(); ChannelStore.setChannelMember(member); - }.bind(this), function(err) { var state = {}; - state.server_error = err.message; + state.serverError = err.message; state.submitting = false; - if (err.message === "Invalid RootId parameter") { - if ($('#post_deleted').length > 0) $('#post_deleted').modal('show'); - } - else { + if (err.message === 'Invalid RootId parameter') { + if ($('#post_deleted').length > 0) { + $('#post_deleted').modal('show'); + } + } else { this.setState(state); } }.bind(this) ); }, commentMsgKeyPress: function(e) { - if (e.which == 13 && !e.shiftKey && !e.altKey) { + if (e.which === 13 && !e.shiftKey && !e.altKey) { e.preventDefault(); this.refs.textbox.getDOMNode().blur(); this.handleSubmit(e); } - var t = new Date().getTime(); + var t = Date.now(); if ((t - this.lastTime) > 5000) { - SocketStore.sendMessage({channel_id: this.props.channelId, action: "typing", props: {"parent_id": this.props.rootId} }); + SocketStore.sendMessage({channel_id: this.props.channelId, action: 'typing', props: {'parent_id': this.props.rootId}}); this.lastTime = t; } }, handleUserInput: function(messageText) { var draft = PostStore.getCommentDraft(this.props.rootId); - if (!draft) { - draft = { previews: [], uploadsInProgress: 0}; - } draft.message = messageText; PostStore.storeCommentDraft(this.props.rootId, draft); - $(".post-right__scroll").scrollTop($(".post-right__scroll")[0].scrollHeight); - $(".post-right__scroll").perfectScrollbar('update'); + $('.post-right__scroll').scrollTop($('.post-right__scroll')[0].scrollHeight); + $('.post-right__scroll').perfectScrollbar('update'); this.setState({messageText: messageText}); }, - handleFileUpload: function(newPreviews) { + handleUploadStart: function(clientIds, channelId) { var draft = PostStore.getCommentDraft(this.props.rootId); - if (!draft) { - draft = { message: '', uploadsInProgress: 0, previews: []} - } - $(".post-right__scroll").scrollTop($(".post-right__scroll")[0].scrollHeight); - $(".post-right__scroll").perfectScrollbar('update'); - var previews = this.state.previews.concat(newPreviews); - var num = this.state.uploadsInProgress; + draft['uploadsInProgress'] = draft['uploadsInProgress'].concat(clientIds); + PostStore.storeCommentDraft(this.props.rootId, draft); - draft.previews = previews; - draft.uploadsInProgress = num-1; + this.setState({uploadsInProgress: draft['uploadsInProgress']}); + }, + handleFileUploadComplete: function(filenames, clientIds, channelId) { + var draft = PostStore.getCommentDraft(this.props.rootId); + + // remove each finished file from uploads + for (var i = 0; i < clientIds.length; i++) { + var index = draft['uploadsInProgress'].indexOf(clientIds[i]); + + if (index !== -1) { + draft['uploadsInProgress'].splice(index, 1); + } + } + + draft['previews'] = draft['previews'].concat(filenames); PostStore.storeCommentDraft(this.props.rootId, draft); - this.setState({previews: previews, uploadsInProgress: num-1}); + this.setState({uploadsInProgress: draft['uploadsInProgress'], previews: draft['previews']}); }, - handleUploadError: function(err) { - this.setState({ server_error: err }); + handleUploadError: function(err, clientId) { + var draft = PostStore.getCommentDraft(this.props.rootId); + + var index = draft['uploadsInProgress'].indexOf(clientId); + if (index !== -1) { + draft['uploadsInProgress'].splice(index, 1); + } + + PostStore.storeCommentDraft(this.props.rootId, draft); + + this.setState({uploadsInProgress: draft['uploadsInProgress'], serverError: err}); }, clearPreviews: function() { this.setState({previews: []}); }, - removePreview: function(filename) { + removePreview: function(id) { var previews = this.state.previews; - for (var i = 0; i < previews.length; i++) { - if (previews[i] === filename) { - previews.splice(i, 1); - break; + var uploadsInProgress = this.state.uploadsInProgress; + + // id can either be the path of an uploaded file or the client id of an in progress upload + var index = previews.indexOf(id); + if (index !== -1) { + previews.splice(index, 1); + } else { + index = uploadsInProgress.indexOf(id); + + if (index !== -1) { + uploadsInProgress.splice(index, 1); + this.refs.fileUpload.cancelUpload(id); } } - var draft = PostStore.getCommentDraft(); - if (!draft) { - draft = { message: '', uploadsInProgress: 0}; - } + var draft = PostStore.getCommentDraft(this.props.rootId); draft.previews = previews; - PostStore.storeCommentDraft(draft); + draft.uploadsInProgress = uploadsInProgress; + PostStore.storeCommentDraft(this.props.rootId, draft); - this.setState({previews: previews}); + this.setState({previews: previews, uploadsInProgress: uploadsInProgress}); }, getInitialState: function() { PostStore.clearCommentDraftUploads(); var draft = PostStore.getCommentDraft(this.props.rootId); - messageText = ''; - uploadsInProgress = 0; - previews = []; - if (draft) { - messageText = draft.message; - uploadsInProgress = draft.uploadsInProgress; - previews = draft.previews - } - return { messageText: messageText, uploadsInProgress: uploadsInProgress, previews: previews, submitting: false }; + return {messageText: draft['message'], uploadsInProgress: draft['uploadsInProgress'], previews: draft['previews'], submitting: false}; }, componentWillReceiveProps: function(newProps) { - if(newProps.rootId !== this.props.rootId) { + if (newProps.rootId !== this.props.rootId) { var draft = PostStore.getCommentDraft(newProps.rootId); - messageText = ''; - uploadsInProgress = 0; - previews = []; - if (draft) { - messageText = draft.message; - uploadsInProgress = draft.uploadsInProgress; - previews = draft.previews - } - this.setState({ messageText: messageText, uploadsInProgress: uploadsInProgress, previews: previews }); + this.setState({messageText: draft['message'], uploadsInProgress: draft['uploadsInProgress'], previews: draft['previews']}); } }, - setUploads: function(val) { - var oldInProgress = this.state.uploadsInProgress - var newInProgress = oldInProgress + val; - - if (newInProgress + this.state.previews.length > Constants.MAX_UPLOAD_FILES) { - newInProgress = Constants.MAX_UPLOAD_FILES - this.state.previews.length; - this.setState({limit_error: "Uploads limited to " + Constants.MAX_UPLOAD_FILES + " files maximum. Please use additional comments for more files."}); - } else { - this.setState({limit_error: null}); - } - - var numToUpload = newInProgress - oldInProgress; - if (numToUpload <= 0) return 0; - - var draft = PostStore.getCommentDraft(this.props.rootId); - if (!draft) { - draft = { message: '', previews: []}; - } - draft.uploadsInProgress = newInProgress; - PostStore.storeCommentDraft(this.props.rootId, draft); - - this.setState({uploadsInProgress: newInProgress}); - - return numToUpload; + getFileCount: function(channelId) { + return this.state.previews.length + this.state.uploadsInProgress.length; }, render: function() { + var serverError = null; + if (this.state.serverError) { + serverError = ( + <div className='form-group has-error'> + <label className='control-label'>{this.state.serverError}</label> + </div> + ); + } - var server_error = this.state.server_error ? <div className='form-group has-error'><label className='control-label'>{ this.state.server_error }</label></div> : null; - var post_error = this.state.post_error ? <label className='control-label'>{this.state.post_error}</label> : null; - var limit_error = this.state.limit_error ? <div className='has-error'><label className='control-label'>{this.state.limit_error}</label></div> : null; + var postError = null; + if (this.state.postError) { + postError = <label className='control-label'>{this.state.postError}</label>; + } - var preview = <div/>; - if (this.state.previews.length > 0 || this.state.uploadsInProgress > 0) { + var preview = null; + if (this.state.previews.length > 0 || this.state.uploadsInProgress.length > 0) { preview = ( <FilePreview files={this.state.previews} @@ -205,32 +200,38 @@ module.exports = React.createClass({ ); } + var postFooterClassName = 'post-create-footer'; + if (postError) { + postFooterClassName += ' has-error'; + } + return ( <form onSubmit={this.handleSubmit}> - <div className="post-create"> - <div id={this.props.rootId} className="post-create-body comment-create-body"> + <div className='post-create'> + <div id={this.props.rootId} className='post-create-body comment-create-body'> <Textbox onUserInput={this.handleUserInput} onKeyPress={this.commentMsgKeyPress} messageText={this.state.messageText} - createMessage="Add a comment..." - initialText="" - id="reply_textbox" - ref="textbox" /> + createMessage='Add a comment...' + initialText='' + id='reply_textbox' + ref='textbox' /> <FileUpload - setUploads={this.setUploads} - onFileUpload={this.handleFileUpload} + ref='fileUpload' + getFileCount={this.getFileCount} + onUploadStart={this.handleUploadStart} + onFileUpload={this.handleFileUploadComplete} onUploadError={this.handleUploadError} /> </div> <MsgTyping channelId={this.props.channelId} parentId={this.props.rootId} /> - <div className={post_error ? 'has-error' : 'post-create-footer'}> - <input type="button" className="btn btn-primary comment-btn pull-right" value="Add Comment" onClick={this.handleSubmit} /> - { post_error } - { server_error } - { limit_error } + <div className={postFooterClassName}> + <input type='button' className='btn btn-primary comment-btn pull-right' value='Add Comment' onClick={this.handleSubmit} /> + {postError} + {serverError} </div> </div> - { preview } + {preview} </form> ); } |