diff options
author | =Corey Hulen <corey@hulen.com> | 2015-06-14 23:53:32 -0800 |
---|---|---|
committer | =Corey Hulen <corey@hulen.com> | 2015-06-14 23:53:32 -0800 |
commit | 56e74239d6b34df8f30ef046f0b0ff4ff0866a71 (patch) | |
tree | 044da29848cf0f5c8607eac34de69065171669cf /web/react/components/create_post.jsx | |
download | chat-56e74239d6b34df8f30ef046f0b0ff4ff0866a71.tar.gz chat-56e74239d6b34df8f30ef046f0b0ff4ff0866a71.tar.bz2 chat-56e74239d6b34df8f30ef046f0b0ff4ff0866a71.zip |
first commit
Diffstat (limited to 'web/react/components/create_post.jsx')
-rw-r--r-- | web/react/components/create_post.jsx | 273 |
1 files changed, 273 insertions, 0 deletions
diff --git a/web/react/components/create_post.jsx b/web/react/components/create_post.jsx new file mode 100644 index 000000000..191be9bf8 --- /dev/null +++ b/web/react/components/create_post.jsx @@ -0,0 +1,273 @@ +// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved. +// See License.txt for license information. + +var AppDispatcher = require('../dispatcher/app_dispatcher.jsx'); +var client = require('../utils/client.jsx'); +var AsyncClient = require('../utils/async_client.jsx'); +var ChannelStore = require('../stores/channel_store.jsx'); +var PostStore = require('../stores/post_store.jsx'); +var UserStore = require('../stores/user_store.jsx'); +var SocketStore = require('../stores/socket_store.jsx'); +var MsgTyping = require('./msg_typing.jsx'); +var Textbox = require('./textbox.jsx'); +var FileUpload = require('./file_upload.jsx'); +var FilePreview = require('./file_preview.jsx'); +var utils = require('../utils/utils.jsx'); + +var Constants = require('../utils/constants.jsx'); +var ActionTypes = Constants.ActionTypes; + +module.exports = React.createClass({ + lastTime: 0, + handleSubmit: function(e) { + e.preventDefault(); + + if (this.state.uploadsInProgress > 0) return; + + if (this.state.submitting) return; + + var post = {}; + post.filenames = []; + + post.message = this.state.messageText; + + var repRegex = new RegExp("<br>", "g"); + if (post.message.replace(repRegex, " ").trim().length === 0 + && this.state.previews.length === 0) { + return; + } + + if (post.message.length > Constants.CHARACTER_LIMIT) { + this.setState({ post_error: 'Post length must be less than '+Constants.CHARACTER_LIMIT+' characters.' }); + return; + } + + this.setState({ submitting: true }); + + var user_id = UserStore.getCurrentId(); + + if (post.message.indexOf("/") == 0) { + client.executeCommand( + this.state.channel_id, + post.message, + false, + function(data) { + PostStore.storeDraft(data.channel_id, user_id, null); + this.setState({ messageText: '', submitting: false, post_error: null, previews: [], server_error: null }); + + if (data.goto_location.length > 0) { + window.location.href = data.goto_location; + } + }.bind(this), + function(err){ + var state = {} + state.server_error = err.message; + state.submitting = false; + this.setState(state); + }.bind(this) + ); + } else { + post.channel_id = this.state.channel_id; + post.filenames = this.state.previews; + + client.createPost(post, ChannelStore.getCurrent(), + function(data) { + PostStore.storeDraft(data.channel_id, data.user_id, null); + this.setState({ messageText: '', submitting: false, post_error: null, previews: [], server_error: null }); + this.resizePostHolder(); + AsyncClient.getPosts(true); + + var channel = ChannelStore.get(this.state.channel_id); + var member = ChannelStore.getMember(this.state.channel_id); + member.msg_count = channel.total_msg_count; + member.last_viewed_at = (new Date).getTime(); + ChannelStore.setChannelMember(member); + + }.bind(this), + function(err) { + var state = {} + state.server_error = err.message; + state.submitting = false; + this.setState(state); + }.bind(this) + ); + } + + $(".post-list-holder-by-time").perfectScrollbar('update'); + }, + componentDidUpdate: function() { + this.resizePostHolder(); + }, + postMsgKeyPress: function(e) { + if (e.which == 13 && !e.shiftKey && !e.altKey) { + e.preventDefault(); + this.refs.textbox.getDOMNode().blur(); + this.handleSubmit(e); + } + + var t = new Date().getTime(); + if ((t - this.lastTime) > 5000) { + SocketStore.sendMessage({channel_id: this.state.channel_id, action: "typing", props: {"parent_id": ""}, state: {} }); + this.lastTime = t; + } + }, + handleUserInput: function(messageText) { + this.resizePostHolder(); + this.setState({messageText: messageText}); + var draft = PostStore.getCurrentDraft(); + if (!draft) { + draft = {} + draft['previews'] = []; + draft['uploadsInProgress'] = 0; + } + draft['message'] = messageText; + PostStore.storeCurrentDraft(draft); + }, + resizePostHolder: function() { + var height = $(window).height() - $(this.refs.topDiv.getDOMNode()).height() - $('#error_bar').outerHeight() - 50; + $(".post-list-holder-by-time").css("height", height + "px"); + $(window).trigger('resize'); + }, + handleFileUpload: function(newPreviews, channel_id) { + var draft = PostStore.getDraft(channel_id, UserStore.getCurrentId()); + if (!draft) { + draft = {} + draft['message'] = ''; + draft['uploadsInProgress'] = 0; + draft['previews'] = []; + } + + if (channel_id === this.state.channel_id) { + var num = this.state.uploadsInProgress; + var oldPreviews = this.state.previews; + var previews = oldPreviews.concat(newPreviews); + + draft['previews'] = previews; + draft['uploadsInProgress'] = num-1; + PostStore.storeCurrentDraft(draft); + + this.setState({previews: previews, uploadsInProgress:num-1}); + } else { + draft['previews'] = draft['previews'].concat(newPreviews); + draft['uploadsInProgress'] = draft['uploadsInProgress'] > 0 ? draft['uploadsInProgress'] - 1 : 0; + PostStore.storeDraft(channel_id, UserStore.getCurrentId(), draft); + } + }, + handleUploadError: function(err) { + this.setState({ server_error: err }); + }, + removePreview: function(filename) { + var previews = this.state.previews; + for (var i = 0; i < previews.length; i++) { + if (previews[i] === filename) { + previews.splice(i, 1); + break; + } + } + var draft = PostStore.getCurrentDraft(); + if (!draft) { + draft = {} + draft['message'] = ''; + draft['uploadsInProgress'] = 0; + } + draft['previews'] = previews; + PostStore.storeCurrentDraft(draft); + this.setState({previews: previews}); + }, + componentDidMount: function() { + ChannelStore.addChangeListener(this._onChange); + this.resizePostHolder(); + }, + componentWillUnmount: function() { + ChannelStore.removeChangeListener(this._onChange); + }, + _onChange: function() { + var channel_id = ChannelStore.getCurrentId(); + if (this.state.channel_id != channel_id) { + var draft = PostStore.getCurrentDraft(); + var previews = []; + var messageText = ''; + var uploadsInProgress = 0; + if (draft) { + previews = draft['previews']; + messageText = draft['message']; + uploadsInProgress = draft['uploadsInProgress']; + } + this.setState({ channel_id: channel_id, messageText: messageText, initialText: messageText, submitting: false, post_error: null, previews: previews, uploadsInProgress: uploadsInProgress }); + } + }, + getInitialState: function() { + PostStore.clearDraftUploads(); + + var draft = PostStore.getCurrentDraft(); + var previews = []; + var messageText = ''; + if (draft) { + previews = draft['previews']; + messageText = draft['message']; + } + return { channel_id: ChannelStore.getCurrentId(), messageText: messageText, uploadsInProgress: 0, previews: previews, submitting: false, initialText: messageText }; + }, + setUploads: function(val) { + var num = this.state.uploadsInProgress + val; + var draft = PostStore.getCurrentDraft(); + if (!draft) { + draft = {} + draft['message'] = ''; + draft['previews'] = []; + } + draft['uploadsInProgress'] = num; + PostStore.storeCurrentDraft(draft); + this.setState({uploadsInProgress: num}); + }, + render: function() { + + 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 preview = <div/>; + if (this.state.previews.length > 0 || this.state.uploadsInProgress > 0) { + preview = ( + <FilePreview + files={this.state.previews} + onRemove={this.removePreview} + uploadsInProgress={this.state.uploadsInProgress} /> + ); + } + var limit_previews = "" + if (this.state.previews.length > 5) { + limit_previews = <div className='has-error'><label className='control-label'>{ "Note: While all files will be available, only first five will show thumbnails." }</label></div> + } + if (this.state.previews.length > 20) { + limit_previews = <div className='has-error'><label className='control-label'>{ "Note: Uploads limited to 20 files maximum. Please use additional posts for more files." }</label></div> + } + + return ( + <form id="create_post" ref="topDiv" role="form" onSubmit={this.handleSubmit}> + <div className="post-create"> + <div className="post-create-body"> + <Textbox + onUserInput={this.handleUserInput} + onKeyPress={this.postMsgKeyPress} + messageText={this.state.messageText} + createMessage="Create a post..." + channelId={this.state.channel_id} + id="post_textbox" + ref="textbox" /> + <FileUpload + setUploads={this.setUploads} + onFileUpload={this.handleFileUpload} + onUploadError={this.handleUploadError} /> + </div> + <div className={post_error ? 'post-create-footer has-error' : 'post-create-footer'}> + { post_error } + { server_error } + { limit_previews } + { preview } + <MsgTyping channelId={this.state.channel_id} parentId=""/> + </div> + </div> + </form> + ); + } +}); |