var App = App || {}; App.Presenters = App.Presenters || {}; App.Presenters.CommentListPresenter = function( _, jQuery, util, promise, api, auth, topNavigationPresenter, messagePresenter) { var $el; var privileges; var templates = {}; var post; var comments = []; function init(params, loaded) { $el = params.$target; post = params.post; comments = params.comments || []; privileges = { canListComments: auth.hasPrivilege(auth.privileges.listComments), canAddComments: auth.hasPrivilege(auth.privileges.addComments), canEditOwnComments: auth.hasPrivilege(auth.privileges.editOwnComments), canEditAllComments: auth.hasPrivilege(auth.privileges.editAllComments), canDeleteOwnComments: auth.hasPrivilege(auth.privileges.deleteOwnComments), canDeleteAllComments: auth.hasPrivilege(auth.privileges.deleteAllComments), canViewUsers: auth.hasPrivilege(auth.privileges.viewUsers), canViewPosts: auth.hasPrivilege(auth.privileges.viewPosts), }; promise.wait( util.promiseTemplate('comment-list'), util.promiseTemplate('comment-list-item'), util.promiseTemplate('comment-form')) .then(function( commentListTemplate, commentListItemTemplate, commentFormTemplate) { templates.commentList = commentListTemplate; templates.commentListItem = commentListItemTemplate; templates.commentForm = commentFormTemplate; render(); loaded(); if (comments.length === 0) { promise.wait(api.get('/comments/' + params.post.id)) .then(function(response) { comments = response.json.comments; render(); }).fail(function() { console.log(arguments); }); } }) .fail(function() { console.log(arguments); loaded(); }); } function render() { $el.html(templates.commentList( _.extend( { commentListItemTemplate: templates.commentListItem, commentFormTemplate: templates.commentForm, util: util, comments: comments, post: post, }, privileges))); $el.find('.comment-add form button[type=submit]').click(function(e) { commentFormSubmitted(e, null); }); renderComments(comments); } function renderComments(comments) { var $target = $el.find('.comments'); var $targetList = $el.find('ul'); if (comments.length > 0) { $target.show(); } else { $target.hide(); } $targetList.empty(); _.each(comments, function(comment) { renderComment($targetList, comment); }); } function renderComment($targetList, comment) { var $item = jQuery('
  • ' + templates.commentListItem({ comment: comment, util: util, canVote: auth.isLoggedIn(), canEditComment: auth.isLoggedIn(comment.user.name) ? privileges.canEditOwnComments : privileges.canEditAllComments, canDeleteComment: auth.isLoggedIn(comment.user.name) ? privileges.canDeleteOwnComments : privileges.canDeleteAllComments, canViewUsers: privileges.canViewUsers, canViewPosts: privileges.canViewPosts, }) + '
  • '); util.loadImagesNicely($item.find('img')); $targetList.append($item); $item.find('a.edit').click(function(e) { e.preventDefault(); editCommentStart($item, comment); }); $item.find('a.delete').click(function(e) { e.preventDefault(); deleteComment(comment); }); $item.find('a.score-up').click(function(e) { e.preventDefault(); score(comment, jQuery(this).hasClass('active') ? 0 : 1); }); $item.find('a.score-down').click(function(e) { e.preventDefault(); score(comment, jQuery(this).hasClass('active') ? 0 : -1); }); } function commentFormSubmitted(e, comment) { e.preventDefault(); var $button = jQuery(e.target); var $form = $button.parents('form'); var sender = $button.val(); if (sender === 'preview') { previewComment($form); } else { submitComment($form, comment); } } function previewComment($form) { var $preview = $form.find('.preview'); $preview.slideUp('fast', function() { $preview.html(util.formatMarkdown($form.find('textarea').val())); $preview.slideDown('fast'); }); } function updateComment(comment) { comments = _.map(comments, function(c) { return c.id === comment.id ? comment : c; }); render(); } function addComment(comment) { comments.push(comment); render(); } function submitComment($form, commentToEdit) { $form.find('.preview').slideUp(); var $textarea = $form.find('textarea'); var data = {text: $textarea.val()}; var p; if (commentToEdit) { p = promise.wait(api.put('/comments/' + commentToEdit.id, data)); } else { p = promise.wait(api.post('/comments/' + post.id, data)); } p.then(function(response) { $textarea.val(''); var comment = response.json.comment; if (commentToEdit) { $form.slideUp(function() { $form.remove(); }); updateComment(comment); } else { addComment(comment); } }).fail(showGenericError); } function editCommentStart($item, comment) { if ($item.find('.comment-form').length > 0) { return; } var $form = jQuery(templates.commentForm({title: 'Edit comment', text: comment.text})); $item.find('.body').append($form); $item.find('form button[type=submit]').click(function(e) { commentFormSubmitted(e, comment); }); } function deleteComment(comment) { if (!window.confirm('Are you sure you want to delete this comment?')) { return; } promise.wait(api.delete('/comments/' + comment.id)) .then(function(response) { comments = _.filter(comments, function(c) { return c.id !== comment.id; }); renderComments(comments); }).fail(showGenericError); } function score(comment, scoreValue) { promise.wait(api.post('/comments/' + comment.id + '/score', {score: scoreValue})) .then(function(response) { comment.score = parseInt(response.json.score); comment.ownScore = parseInt(response.json.ownScore); updateComment(comment); }).fail(showGenericError); } function showGenericError(response) { window.alert(response.json && response.json.error || response); } return { init: init, render: render, }; }; App.DI.register('commentListPresenter', ['_', 'jQuery', 'util', 'promise', 'api', 'auth', 'topNavigationPresenter', 'messagePresenter'], App.Presenters.CommentListPresenter);