diaspora/app/assets/javascripts/app/views/comment_stream_view.js
2017-08-17 11:40:49 +02:00

181 lines
5.4 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",
"click .toggle_post_comments": "expandComments",
"click form": "openForm"
},
initialize: function() {
this.CommentView = app.views.Comment;
this.setupBindings();
},
setupBindings: function() {
this.model.comments.bind("add", this.appendComment, this);
this.model.comments.bind("remove", this.removeComment, this);
$(document.body).click(this.onFormBlur.bind(this));
},
postRenderTemplate : function() {
this.model.comments.each(this.appendComment, this);
this.commentBox = this.$(".comment_box");
this.commentSubmitButton = this.$("input[name='commit']");
this.mentions = new app.views.CommentMention({el: this.$el, postId: this.model.get("id")});
this.mdEditor = new Diaspora.MarkdownEditor(this.$(".comment_box"), {
onPreview: function($mdInstance) {
var renderedText = app.helpers.textFormatter($mdInstance.getContent(), this.mentions.getMentionedPeople());
return "<div class='preview-content'>" + renderedText + "</div>";
}.bind(this),
onFocus: this.openForm.bind(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.commentBox.val());
if (commentText === "") {
this.commentBox.focus();
return;
}
this.disableCommentBox();
this.model.comment(commentText, {
success: function() {
this.commentBox.val("");
this.enableCommentBox();
this.mdEditor.hidePreview();
this.closeForm();
autosize.update(this.commentBox);
}.bind(this),
error: function() {
this.enableCommentBox();
this.mdEditor.hidePreview();
this.openForm();
}.bind(this)
});
},
disableCommentBox: function() {
this.commentBox.prop("disabled", true);
this.commentSubmitButton.prop("disabled", true);
},
enableCommentBox: function() {
this.commentBox.removeAttr("disabled");
this.commentSubmitButton.removeAttr("disabled");
},
keyDownOnCommentBox: function(evt) {
if (evt.which === Keycodes.ENTER && (evt.metaKey || 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 commentView = new this.CommentView({model: comment});
var commentHtml = commentView.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 if (this._insertPoint <= 0) {
this.$(".comments").prepend(commentHtml);
} else {
commentBlocks.eq(this._insertPoint).before(commentHtml);
}
commentView.renderPluginWidgets();
},
removeComment: function(comment) {
this.$("#" + comment.get("guid")).closest(".comment.media").remove();
},
expandComments: function(evt){
this.$(".loading-comments").removeClass("hidden");
if(evt){ evt.preventDefault(); }
this.model.comments.fetch({
success: function() {
this.$("div.comment.show_comments").addClass("hidden");
this.$(".loading-comments").addClass("hidden");
}.bind(this)
});
},
openForm: function() {
this.$("form").addClass("open");
this.$(".md-editor").addClass("active");
},
closeForm: function() {
this.$("form").removeClass("open");
this.$(".md-editor").removeClass("active");
this.commentBox.blur();
autosize.update(this.commentBox);
},
isCloseAllowed: function() {
if (this.mdEditor === undefined) {
return true;
}
return !this.mdEditor.isPreviewMode() && this.mdEditor.userInputEmpty();
},
onFormBlur: function(evt) {
if (!this.isCloseAllowed()) {
return;
}
var $target = $(evt.target);
var isForm = $target.hasClass("new-comment") || $target.parents(".new-comment").length !== 0;
if (!isForm && !$target.hasClass("focus_comment_textarea")) {
this.closeForm();
}
}
});
// @license-end