added client predictive commenting
Этот коммит содержится в:
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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({
|
||||
|
||||
Ссылка в новой задаче
Block a user