diff options
Diffstat (limited to 'web')
-rw-r--r-- | web/react/components/create_comment.jsx | 24 | ||||
-rw-r--r-- | web/react/components/create_post.jsx | 30 | ||||
-rw-r--r-- | web/react/components/post_info.jsx | 7 | ||||
-rw-r--r-- | web/react/components/post_right.jsx | 53 |
4 files changed, 97 insertions, 17 deletions
diff --git a/web/react/components/create_comment.jsx b/web/react/components/create_comment.jsx index 885efab7a..fbb05c77f 100644 --- a/web/react/components/create_comment.jsx +++ b/web/react/components/create_comment.jsx @@ -2,15 +2,16 @@ // See License.txt for license information. var client = require('../utils/client.jsx'); -var AsyncClient =require('../utils/async_client.jsx'); +var AsyncClient = require('../utils/async_client.jsx'); var SocketStore = require('../stores/socket_store.jsx'); var ChannelStore = require('../stores/channel_store.jsx'); +var UserStore = require('../stores/user_store.jsx'); var PostStore = require('../stores/post_store.jsx'); var Textbox = require('./textbox.jsx'); var MsgTyping = require('./msg_typing.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'); module.exports = React.createClass({ @@ -39,10 +40,16 @@ module.exports = React.createClass({ return; } + var user_id = UserStore.getCurrentId(); + post.channel_id = this.props.channelId; post.root_id = this.props.rootId; - post.parent_id = this.props.parentId; + post.parent_id = this.props.rootId; post.filenames = this.state.previews; + var time = utils.getTimestamp(); + post.pending_post_id = user_id + ":"+ time; + post.user_id = user_id; + post.create_at = time; this.setState({submitting: true, serverError: null}); @@ -69,10 +76,19 @@ module.exports = React.createClass({ $('#post_deleted').modal('show'); } } else { - this.setState(state); + post.did_fail = true; + PostStore.updatePendingPost(post); } + + state.submitting = false; + this.setState(state); }.bind(this) ); + + post.is_loading = true; + PostStore.storePendingPost(post); + PostStore.storeCommentDraft(this.props.rootId, null); + this.setState({ messageText: '', submitting: false, post_error: null, previews: [], server_error: null, limit_error: null }); }, commentMsgKeyPress: function(e) { if (e.which === 13 && !e.shiftKey && !e.altKey) { diff --git a/web/react/components/create_post.jsx b/web/react/components/create_post.jsx index 76f2bf262..8110f5886 100644 --- a/web/react/components/create_post.jsx +++ b/web/react/components/create_post.jsx @@ -214,20 +214,34 @@ module.exports = React.createClass({ var channelId = ChannelStore.getCurrentId(); if (this.state.channelId !== channelId) { var draft = PostStore.getCurrentDraft(); - this.setState({ - channelId: channelId, messageText: draft['message'], initialText: draft['message'], submitting: false, - serverError: null, postError: null, previews: draft['previews'], uploadsInProgress: draft['uploadsInProgress'] - }); + + var previews = []; + var messageText = ''; + var uploadsInProgress = 0; + if (draft && draft['previews'] && draft['message']) { + previews = draft['previews']; + messageText = draft['message']; + uploadsInProgress = draft['uploadsInProgress']; + } + + this.setState({channelId: channelId, messageText: messageText, initialText: messageText, submitting: false, serverError: null, postError: null, previews: previews, uploadsInProgress: uploadsInProgress}); } }, getInitialState: function() { PostStore.clearDraftUploads(); + PostStore.clearPendingPosts(ChannelStore.getCurrentId()); var draft = PostStore.getCurrentDraft(); - return { - channelId: ChannelStore.getCurrentId(), messageText: draft['message'], uploadsInProgress: draft['uploadsInProgress'], - previews: draft['previews'], submitting: false, initialText: draft['message'] - }; + var previews = []; + var messageText = ''; + var uploadsInProgress = 0; + if (draft && draft["previews"] && draft["message"]) { + previews = draft['previews']; + messageText = draft['message']; + uploadsInProgress = draft['uploadsInProgress']; + } + + return { channelId: ChannelStore.getCurrentId(), messageText: messageText, uploadsInProgress: uploadsInProgress, previews: previews, submitting: false, initialText: messageText}; }, getFileCount: function(channelId) { if (channelId === this.state.channelId) { diff --git a/web/react/components/post_info.jsx b/web/react/components/post_info.jsx index 8eaaf4e8c..93d028e18 100644 --- a/web/react/components/post_info.jsx +++ b/web/react/components/post_info.jsx @@ -22,16 +22,19 @@ module.exports = React.createClass({ var comments = ""; var lastCommentClass = this.props.isLastComment ? " comment-icon__container__show" : " comment-icon__container__hide"; - if (this.props.commentCount >= 1) { + if (this.props.commentCount >= 1 && !post.did_fail && !post.is_loading) { comments = <a href="#" className={"comment-icon__container theme" + lastCommentClass} onClick={this.props.handleCommentClick}><span className="comment-icon" dangerouslySetInnerHTML={{__html: Constants.COMMENT_ICON }} />{this.props.commentCount}</a>; } + var show_dropdown = isOwner || (this.props.allowReply === "true" && type != "Comment"); + if (post.did_fail || post.is_loading) show_dropdown = false; + return ( <ul className="post-header post-info"> <li className="post-header-col"><time className="post-profile-time">{ utils.displayDateTime(post.create_at) }</time></li> <li className="post-header-col post-header__reply"> <div className="dropdown"> - { isOwner || (this.props.allowReply === "true" && type != "Comment") ? + { show_dropdown ? <div> <a href="#" className="dropdown-toggle theme" type="button" data-toggle="dropdown" aria-expanded="false" /> <ul className="dropdown-menu" role="menu"> diff --git a/web/react/components/post_right.jsx b/web/react/components/post_right.jsx index e46979ff7..69e514e11 100644 --- a/web/react/components/post_right.jsx +++ b/web/react/components/post_right.jsx @@ -12,6 +12,7 @@ var CreateComment = require( './create_comment.jsx' ); var Constants = require('../utils/constants.jsx'); var FileAttachmentList = require('./file_attachment_list.jsx'); var FileUploadOverlay = require('./file_upload_overlay.jsx'); +var client = require('../utils/client.jsx'); var ActionTypes = Constants.ActionTypes; RhsHeaderPost = React.createClass({ @@ -119,10 +120,36 @@ RootPost = React.createClass({ }); CommentPost = React.createClass({ + retryComment: function(e) { + e.preventDefault(); + + var post = this.props.post; + client.createPost(post, post.channel_id, + function(data) { + AsyncClient.getPosts(true); + + var member = ChannelStore.getMember(post.channel_id); + member.msg_count = channel.total_msg_count; + member.last_viewed_at = (new Date).getTime(); + ChannelStore.setChannelMember(member); + }.bind(this), + function(err) { + post.did_fail = true; + PostStore.updatePendingPost(post); + this.forceUpdate(); + }.bind(this) + ); + + post.did_fail = false; + post.is_loading = true; + PostStore.updatePendingPost(post); + this.forceUpdate(); + }, render: function() { var post = this.props.post; var commentClass = "post"; + var post = this.props.post; var currentUserCss = ""; if (UserStore.getCurrentId() === post.user_id) { @@ -139,6 +166,16 @@ CommentPost = React.createClass({ var message = utils.textToJsx(post.message); var timestamp = UserStore.getCurrentUser().update_at; + var loading; + var postClass = ""; + if (post.did_fail) { + postClass += " post-fail"; + loading = <a className="post-retry pull-right" href="#" onClick={this.retryComment}>Retry</a>; + } else if (post.is_loading) { + postClass += " post-waiting"; + loading = <img className="post-loading-gif pull-right" src="/static/images/load.gif"/>; + } + return ( <div className={commentClass + " " + currentUserCss}> <div className="post-profile-img__container"> @@ -149,7 +186,7 @@ CommentPost = React.createClass({ <li className="post-header-col"><strong><UserProfile userId={post.user_id} /></strong></li> <li className="post-header-col"><time className="post-right-comment-time">{ utils.displayDateTime(post.create_at) }</time></li> <li className="post-header-col post-header__reply"> - { isOwner ? + { isOwner && !post.did_fail && !post.is_loading ? <div className="dropdown" onClick={function(e){$('.post-list-holder-by-time').scrollTop($(".post-list-holder-by-time").scrollTop() + 50);}}> <a href="#" className="dropdown-toggle theme" type="button" data-toggle="dropdown" aria-expanded="false" /> <ul className="dropdown-menu" role="menu"> @@ -161,7 +198,7 @@ CommentPost = React.createClass({ </li> </ul> <div className="post-body"> - <p>{message}</p> + <p className={postClass}>{loading}{message}</p> { post.filenames && post.filenames.length > 0 ? <FileAttachmentList filenames={post.filenames} @@ -177,7 +214,17 @@ CommentPost = React.createClass({ }); function getStateFromStores() { - return { post_list: PostStore.getSelectedPost() }; + var post_list = PostStore.getSelectedPost(); + if (!post_list || post_list.order.length < 1) return { post_list: {} }; + + var channel_id = post_list.posts[post_list.order[0]].channel_id; + var pending_post_list = PostStore.getPendingPosts(channel_id); + + if (pending_post_list) { + for (var pid in pending_post_list.posts) { post_list.posts[pid] = pending_post_list.posts[pid] }; + } + + return { post_list: post_list }; } module.exports = React.createClass({ |