diff --git a/pillar/web/nodes/custom/comments.py b/pillar/web/nodes/custom/comments.py index a44ac645..f61fae8a 100644 --- a/pillar/web/nodes/custom/comments.py +++ b/pillar/web/nodes/custom/comments.py @@ -124,43 +124,6 @@ def format_comment(comment, is_reply=False, is_team=False, replies=None): replies=replies) -@blueprint.route("/comments/") -def comments_index(): - warnings.warn('comments_index() is deprecated in favour of comments_for_node()') - - parent_id = request.args.get('parent_id') - # Get data only if we format it - api = system_util.pillar_api() - if request.args.get('format') == 'json': - nodes = Node.all({ - 'where': '{"node_type" : "comment", "parent": "%s"}' % (parent_id), - 'embedded': '{"user":1}'}, api=api) - - comments = [] - for comment in nodes._items: - # Query for first level children (comment replies) - replies = Node.all({ - 'where': '{"node_type" : "comment", "parent": "%s"}' % (comment._id), - 'embedded': '{"user":1}'}, api=api) - replies = replies._items if replies._items else None - if replies: - replies = [format_comment(reply, is_reply=True) for reply in replies] - - comments.append( - format_comment(comment, is_reply=False, replies=replies)) - - return_content = jsonify(items=[c for c in comments if c is not None]) - else: - parent_node = Node.find(parent_id, api=api) - project = Project({'_id': parent_node.project}) - has_method_POST = project.node_type_has_method('comment', 'POST', api=api) - # Data will be requested via javascript - return_content = render_template('nodes/custom/_comments.html', - parent_id=parent_id, - has_method_POST=has_method_POST) - return return_content - - @blueprint.route('//comments') def comments_for_node(node_id): """Shows the comments attached to the given node.""" diff --git a/src/templates/nodes/custom/_comments.jade b/src/templates/nodes/custom/_comments.jade deleted file mode 100644 index f7f02e2d..00000000 --- a/src/templates/nodes/custom/_comments.jade +++ /dev/null @@ -1,447 +0,0 @@ - -#comments-container - a(name="comments") - - section#comments-list - .comment-reply-container - | {% if current_user.is_authenticated %} - - | {% if has_method_POST %} - .comment-reply-avatar - img(src="{{ current_user.gravatar }}") - - .comment-reply-form - - .comment-reply-field - textarea( - id="comment_field", - data-parent_id="{{ parent_id }}", - placeholder="Join the conversation...",) - - .comment-reply-meta - .comment-details - .comment-rules - a( - title="Markdown Supported" - href="https://guides.github.com/features/mastering-markdown/") - i.pi-markdown - - .comment-author - span.commenting-as commenting as - span.author-name {{ current_user.full_name }} - - button.comment-action-cancel.btn.btn-outline( - type="button", - title="Cancel") - i.pi-cancel - button.comment-action-submit.btn.btn-outline( - id="comment_submit", - type="button", - title="Post Comment") - | Post Comment - span.hint (Ctrl+Enter) - - .comment-reply-preview - - | {% else %} - - | {# * It's authenticated, but has no 'POST' permission #} - .comment-reply-form - .comment-reply-field.sign-in - textarea( - disabled, - id="comment_field", - data-parent_id="{{ parent_id }}", - placeholder="") - .sign-in - | Join the conversation! Subscribe to Blender Cloud now. - | {% endif %} - - | {% else %} - | {# * It's not autenticated #} - .comment-reply-form - .comment-reply-field.sign-in - textarea( - disabled, - id="comment_field", - data-parent_id="{{ parent_id }}", - placeholder="") - .sign-in - a(href="{{ url_for('users.login') }}") Log in - | to comment. - - | {% endif %} - - section#comments-list-header - #comments-list-title - #comments-list-items - #comments-list-items-loading - i.pi-spin - - script#comment-template(type="text/x-handlebars-template") - | {% raw %} - - | {{#list items }} - - .comment-container( - id="{{ _id }}", - data-node_id="{{ _id }}", - class="{{#if is_team}}is-team{{/if}}{{#if is_reply}}is-reply{{else}}is-first{{/if}}") - - .comment-header - .comment-avatar - img(src="{{ gravatar }}") - - .comment-author(class="{{#if is_own}}own{{/if}}") - | {{ author }} - span.username ({{ author_username }}) - - | {{#if is_team}} - .comment-badge.badge-team(title="Project Member") team - | {{/if}} - - .comment-time {{ time_published }} {{#if time_edited }} (edited {{ time_edited }}){{/if}} - - .comment-content {{{ content }}} - | {{#if is_own}} - .comment-content-preview - | {{/if}} - - .comment-meta - .comment-rating( - class="{{#if is_rated}}rated{{/if}}{{#if is_rated_positive}} positive{{/if}}") - .comment-rating-value(title="Number of likes") {{ rating }} - | {{#unless is_own}} - .comment-action-rating.up(title="Like comment") - | {{/unless}} - - .comment-action-reply(title="Reply to this comment") - span reply - | {{#if is_own}} - .comment-action-edit - span.edit_mode(title="Edit comment") edit - span.edit_save(title="Save comment") - i.pi-check - | save changes - span.edit_cancel(title="Cancel changes") - i.pi-cancel - | cancel - | {{/if}} - - | {{/list}} - | {% endraw %} - - -| {% block comment_scripts %} - -script. - // Markdown initialization - var convert = new Markdown.getSanitizingConverter(); - Markdown.Extra.init(convert); - convert = convert.makeHtml; - - // Define the template for handlebars - var source = $("#comment-template").html(); - var template = Handlebars.compile(source); - - - // Register the helper for generating the comments list - Handlebars.registerHelper('list', function(context, options) { - var ret = ""; - var comments_count = 0 - - // Loop through all first-level comments - for(var i=0, j=context.length; i 0) ? comments_count : 'No') + ((comments_count == 1) ? ' comment' : ' comments')); - - return ret; - }); - - // Helper for the if/else statement - Handlebars.registerHelper('if', function(conditional, options) { - if(conditional) { - return options.fn(this); - } else { - return options.inverse(this); - } - }); - - - /* Build the markdown preview when typing in textarea */ - $(function() { - var $textarea = $('.comment-reply-field textarea'), - $container = $('.comment-reply-form'), - $preview = $('.comment-reply-preview'); - - // As we type in the textarea - $textarea.keyup(function(e) { - - // Convert markdown - $preview.html(convert($textarea.val())); - - // While we are at it, style when empty - if ($textarea.val()) { - $container.addClass('filled'); - } else { - $container.removeClass('filled'); - }; - - // Send on ctrl+enter - if ((e.keyCode == 10 || e.keyCode == 13) && e.ctrlKey){ - $( ".comment-action-submit" ).trigger( "click" ); - }; - - }).trigger('keyup'); - }); - - - // Get the comments list in JSON - $.getJSON( "{{url_for('nodes.comments_index')}}?parent_id={{ parent_id }}&format=json", function( data ) { - // Format using handlebars template - var comments = template(data); - - if (comments && comments.trim() !="") { - $('#comments-list-items').html(comments); - } else { - $('#comments-list-items').html(''); - } - }) - .done(function(){ - var scrollToId = location.hash; - if (scrollToId.length <= 1) return; - - document.getElementById(scrollToId.substr(1)).scrollIntoView(true); - $(scrollToId).addClass('comment-linked'); - }); - - /* Submit comment */ - $('.comment-action-submit').click(function(e){ - - var $this = $(this); - var $textarea = $('.comment-reply-field textarea'); - var commentField = document.getElementById('comment_field'); - var comment = commentField.value; - - function error(msg) { - // No content in the textarea - $this.addClass('button-field-error'); - $textarea.addClass('field-error') - $this.html(msg); - - setTimeout(function(){ - $this.html('Post Comment'); - $this.removeClass('button-field-error'); - $textarea.removeClass('field-error'); - }, 2500); - } - - if (comment.length < 5) { - if (comment.length == 0) error("Say something..."); - else error("Minimum 5 characters."); - return; - } - - $this.addClass('submitting'); - $this.html(' Posting...'); - - // Collect parent_id - parent_id = commentField.getAttribute('data-parent_id'); - - $.post("{{url_for('nodes.comments_create')}}", - // Submit content and parent_id for comment creation - {'content': comment, 'parent_id': parent_id} - ) - .fail(function(){ - $this.addClass('button-field-error'); - $textarea.addClass('field-error') - $this.html("Houston! Try again?"); - - setTimeout(function(){ - $this.html('Post Comment'); - $this.removeClass('button-field-error'); - $textarea.removeClass('field-error'); - }, 2500); - }) - .done(function(){ - // Load the comments - var url = "{{url_for('nodes.comments_index')}}?parent_id={{ parent_id }}"; - $.get(url, function(dataHtml) { - // Update the DOM injecting the generate HTML into the page - $('#comments-container').replaceWith(dataHtml); - }) - }); - }); - - - /* Edit comment */ - - // Markdown convert as we type in the textarea - $(document).on('keyup','body .comment-content textarea',function(e){ - - var $textarea = $(this), - $container = $(this).parent(), - $preview = $container.next(); - - // Convert markdown - $preview.html(convert($textarea.val())); - - // While we are at it, style if empty - if (!$textarea.val()) { - $container.addClass('empty'); - } else { - $container.removeClass('empty'); - }; - }).trigger('keyup'); - - - /* Enter edit mode */ - $(document).on('click','body .comment-action-edit span.edit_mode',function(){ - - $(this).hide(); - $(this).siblings('span.edit_cancel').show(); - $(this).siblings('span.edit_save').show(); - - var comment_content = $(this).parent().parent().siblings('.comment-content'); - var comment_id = comment_content.parent().attr('data-node_id'); - var height = comment_content.height(); - var url = '/nodes/' + comment_id + '/view?format=json'; - - $.get(url, function(data) { - var comment_raw = data['node']['properties']['content']; - comment_content.html(''); - - comment_content.addClass('editing') - .find('textarea') - .height(height) - .focus(); - comment_content.siblings('.comment-content-preview').show(); - }) - .fail(function(data){ - statusBarSet('error', 'Error entering edit mode.', 'pi-warning'); - }); - }); - - /* Return UI to normal, when cancelling or saving */ - function commentEditCancel(comment_container) { - var comment_id = comment_container.parent().attr('id'); - var url = '/nodes/' + comment_id + '/view?format=json'; - - $.get(url, function(data) { - var comment_raw = data['node']['properties']['content']; - - comment_container.html(convert(comment_raw)) - .removeClass('editing'); - comment_container.siblings('.comment-content-preview').html('').hide(); - }) - .fail(function(data){ - statusBarSet('error', 'Error canceling.', 'pi-warning'); - }); - } - - $(document).on('click','body .comment-action-edit span.edit_cancel',function(e){ - - $(this).hide(); - $(this).siblings('span.edit_save').hide(); - $(this).siblings('span.edit_mode').show(); - - var commentContainer = $(this).parent().parent().siblings('.comment-content'); - commentEditCancel(commentContainer); - }); - - /* Save edited comment */ - $(document).on('click','body .comment-action-edit span.edit_save',function(e){ - - var $this = $(this); - var commentContainer = $(this).parent().parent().siblings('.comment-content'); - var commentField = commentContainer.find('textarea'); - var comment = commentField.val(); - var commentId = commentContainer.parent().attr('id'); - - function error(msg) { - // No content in the textarea - $this.addClass('error') - .html(msg); - commentField.addClass('field-error') - - setTimeout(function(){ - $this.html(' save changes') - .removeClass('error'); - commentField.removeClass('field-error'); - }, 2500); - } - - if (comment.length < 5) { - if (comment.length == 0) error("Say something..."); - else error("Minimum 5 characters."); - return; - } - - $this.addClass('saving') - .html(' Saving...'); - - $.post('/nodes/comments/' + commentId, - {'content': comment} - ) - .fail(function(){ - $this.addClass('error') - .html("Houston! Try again?"); - commentField.addClass('field-error') - - setTimeout(function(){ - $this.html('Save changes') - .removeClass('error'); - commentField.removeClass('field-error'); - }, 2500); - }) - .done(function(){ - - commentEditCancel(commentContainer); - commentContainer - .html(convert(comment)); - commentContainer.next().text(comment); - - $this.html(' saved!') - .removeClass('saving') - .siblings('span.edit_cancel').hide(); - - setTimeout(function(){ - $this.html(' save changes') - .hide() - .siblings('span.edit_mode').show(); - }, 2500); - }); - }); - -| {% endblock %}