If you look at comment expand process with javascript debugger, you
will notice that at first comments get added to existing stream ("add"
event handler of model.comments gets launched because of model.comments.fetch).
Then the comment stream gets empty and then filled by the postRenderTemplate
handler.
This patch removes comments rerendering on the expansion. The fetching process is
changed so that older comments are added to the correct place, so the order
looks nice without rerendering. Thus, unnecessary job of rerendering is avoided.
114 lines
3.3 KiB
JavaScript
114 lines
3.3 KiB
JavaScript
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later
|
|
|
|
app.views.CommentStream = app.views.Base.extend({
|
|
|
|
templateName: "comment-stream",
|
|
|
|
className : "comment_stream",
|
|
|
|
events: {
|
|
"keydown .comment_box": "keyDownOnCommentBox",
|
|
"submit form": "createComment",
|
|
"focus .comment_box": "commentTextareaFocused",
|
|
"click .toggle_post_comments": "expandComments"
|
|
},
|
|
|
|
initialize: function(options) {
|
|
this.commentTemplate = options.commentTemplate;
|
|
|
|
this.setupBindings();
|
|
},
|
|
|
|
setupBindings: function() {
|
|
this.model.comments.bind('add', this.appendComment, this);
|
|
},
|
|
|
|
postRenderTemplate : function() {
|
|
this.model.comments.each(this.appendComment, this);
|
|
},
|
|
|
|
presenter: function(){
|
|
return _.extend(this.defaultPresenter(), {
|
|
moreCommentsCount : (this.model.interactions.commentsCount() - 3),
|
|
showExpandCommentsLink : (this.model.interactions.commentsCount() > 3),
|
|
commentsCount : this.model.interactions.commentsCount()
|
|
});
|
|
},
|
|
|
|
createComment: function(evt) {
|
|
if(evt){ evt.preventDefault(); }
|
|
|
|
var commentText = $.trim(this.$('.comment_box').val());
|
|
this.$(".comment_box").val("");
|
|
this.$(".comment_box").css("height", "");
|
|
if(commentText) {
|
|
this.model.comment(commentText);
|
|
return this;
|
|
} else {
|
|
this.$(".comment_box").focus();
|
|
}
|
|
},
|
|
|
|
keyDownOnCommentBox: function(evt) {
|
|
if(evt.which === Keycodes.ENTER && evt.ctrlKey) {
|
|
this.$("form").submit();
|
|
return false;
|
|
}
|
|
},
|
|
|
|
_insertPoint: 0, // An index of the comment added in the last call of this.appendComment
|
|
|
|
// This adjusts this._insertPoint according to timestamp value
|
|
_moveInsertPoint: function(timestamp, commentBlocks) {
|
|
if (commentBlocks.length === 0) {
|
|
this._insertPoint = 0;
|
|
return;
|
|
}
|
|
|
|
if (this._insertPoint > commentBlocks.length) {
|
|
this._insertPoint = commentBlocks.length;
|
|
}
|
|
|
|
while (this._insertPoint > 0 && timestamp < commentBlocks.eq(this._insertPoint - 1).find("time").attr("datetime")) {
|
|
this._insertPoint--;
|
|
}
|
|
while (this._insertPoint < commentBlocks.length &&
|
|
timestamp > commentBlocks.eq(this._insertPoint).find("time").attr("datetime")) {
|
|
this._insertPoint++;
|
|
}
|
|
},
|
|
|
|
appendComment: function(comment) {
|
|
// Set the post as the comment's parent, so we can check
|
|
// on post ownership in the Comment view.
|
|
comment.set({parent : this.model.toJSON()});
|
|
|
|
var commentHtml = new app.views.Comment({model: comment}).render().el;
|
|
var commentBlocks = this.$(".comments div.comment.media");
|
|
this._moveInsertPoint(comment.get("created_at"), commentBlocks);
|
|
if (this._insertPoint === commentBlocks.length) {
|
|
this.$(".comments").append(commentHtml);
|
|
} else {
|
|
commentBlocks.eq(this._insertPoint).before(commentHtml);
|
|
}
|
|
this._insertPoint++;
|
|
},
|
|
|
|
commentTextareaFocused: function(){
|
|
this.$("form").removeClass('hidden').addClass("open");
|
|
},
|
|
|
|
expandComments: function(evt){
|
|
if(evt){ evt.preventDefault(); }
|
|
var self = this;
|
|
|
|
this.model.comments.fetch({
|
|
success : function(resp){
|
|
self.$("div.comment.show_comments").addClass("hidden");
|
|
|
|
self.model.trigger("commentsExpanded", self);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
// @license-end
|