Removed obsolete comment file + function
This commit is contained in:
@@ -124,43 +124,6 @@ def format_comment(comment, is_reply=False, is_team=False, replies=None):
|
|||||||
replies=replies)
|
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('/<string(length=24):node_id>/comments')
|
@blueprint.route('/<string(length=24):node_id>/comments')
|
||||||
def comments_for_node(node_id):
|
def comments_for_node(node_id):
|
||||||
"""Shows the comments attached to the given node."""
|
"""Shows the comments attached to the given node."""
|
||||||
|
@@ -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! <a href="https://store.blender.org/product/membership/">Subscribe to Blender Cloud now.</a>
|
|
||||||
| {% 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<j; i++) {
|
|
||||||
|
|
||||||
comments_count++
|
|
||||||
|
|
||||||
// Convert Markdown for each comment
|
|
||||||
context[i]['content'] = convert(context[i]['content']);
|
|
||||||
|
|
||||||
// Append compiled comment to return string
|
|
||||||
ret = ret + options.fn(context[i]);
|
|
||||||
|
|
||||||
// Search for replies to the current comment
|
|
||||||
if (context[i]['replies']) {
|
|
||||||
|
|
||||||
var replies = context[i]['replies'];
|
|
||||||
var compiled_replies = "";
|
|
||||||
|
|
||||||
// Loop through replies
|
|
||||||
for(var r=0, t=replies.length; r<t; r++) {
|
|
||||||
|
|
||||||
// Convert Markdown for each comment
|
|
||||||
replies[r]['content'] = convert(replies[r]['content']);
|
|
||||||
|
|
||||||
// Append compiled replies
|
|
||||||
compiled_replies = compiled_replies + options.fn(replies[r]);
|
|
||||||
comments_count++
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append replies list to the return string
|
|
||||||
ret = ret + compiled_replies;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$("#comments-list-title").html(((comments_count > 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('<i class="pi-spin spin"></i> 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('<textarea>' + comment_raw + '</textarea>');
|
|
||||||
|
|
||||||
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('<i class="pi-check"></i> 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('<i class="pi-spin spin"></i> 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('<i class="pi-grin"></i> saved!')
|
|
||||||
.removeClass('saving')
|
|
||||||
.siblings('span.edit_cancel').hide();
|
|
||||||
|
|
||||||
setTimeout(function(){
|
|
||||||
$this.html('<i class="pi-check"></i> save changes')
|
|
||||||
.hide()
|
|
||||||
.siblings('span.edit_mode').show();
|
|
||||||
}, 2500);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
| {% endblock %}
|
|
Reference in New Issue
Block a user