diff --git a/lms/djangoapps/django_comment_client/base/urls.py b/lms/djangoapps/django_comment_client/base/urls.py index f2cb4ccb15..1a2715763d 100644 --- a/lms/djangoapps/django_comment_client/base/urls.py +++ b/lms/djangoapps/django_comment_client/base/urls.py @@ -10,6 +10,7 @@ urlpatterns = patterns('django_comment_client.base.views', url(r'threads/(?P[\w\-]+)/reply$', 'create_comment', name='create_comment'), url(r'threads/(?P[\w\-]+)/delete', 'delete_thread', name='delete_thread'), url(r'threads/(?P[\w\-]+)/upvote$', 'vote_for_thread', {'value': 'up'}, name='upvote_thread'), + url(r'threads/(?P[\w\-]+)/flagAbuse$', 'flag_abuse_for_thread', {'value': 'up'}, name='flag_abuse_thread'), url(r'threads/(?P[\w\-]+)/downvote$', 'vote_for_thread', {'value': 'down'}, name='downvote_thread'), url(r'threads/(?P[\w\-]+)/unvote$', 'undo_vote_for_thread', name='undo_vote_for_thread'), url(r'threads/(?P[\w\-]+)/follow$', 'follow_thread', name='follow_thread'), diff --git a/lms/djangoapps/django_comment_client/base/views.py b/lms/djangoapps/django_comment_client/base/views.py index 63d69427c9..d821c939f2 100644 --- a/lms/djangoapps/django_comment_client/base/views.py +++ b/lms/djangoapps/django_comment_client/base/views.py @@ -136,7 +136,7 @@ def _create_comment(request, course_id, thread_id=None, parent_id=None): user = cc.User.from_django_user(request.user) user.follow(comment.thread) if request.is_ajax(): - return ajax_content_response(request, course_id, comment.to_dict(), 'discussion/ajax_create_comment.html') + return ajax_content_response(request, course_id,comment.to_dict(), 'discussion/ajax_create_comment.html') else: return JsonResponse(utils.safe_content(comment.to_dict())) @@ -235,6 +235,15 @@ def vote_for_thread(request, course_id, thread_id, value): user.vote(thread, value) return JsonResponse(utils.safe_content(thread.to_dict())) +@require_POST +@login_required +@permitted +def flag_abuse_for_thread(request, course_id, thread_id, value): + user = cc.User.from_django_user(request.user) + thread = cc.Thread.find(thread_id) + thread.flagAbuse(thread, value) + return JsonResponse(utils.safe_content(thread.to_dict())) + @require_POST @login_required @permitted diff --git a/lms/djangoapps/django_comment_client/permissions.py b/lms/djangoapps/django_comment_client/permissions.py index b95a890dda..10a5f748e9 100644 --- a/lms/djangoapps/django_comment_client/permissions.py +++ b/lms/djangoapps/django_comment_client/permissions.py @@ -85,6 +85,7 @@ VIEW_PERMISSIONS = { 'vote_for_comment' : [['vote', 'is_open']], 'undo_vote_for_comment': [['unvote', 'is_open']], 'vote_for_thread' : [['vote', 'is_open']], + 'flag_abuse_for_thread': [['vote', 'is_open']], 'undo_vote_for_thread': [['unvote', 'is_open']], 'follow_thread' : ['follow_thread'], 'follow_commentable': ['follow_commentable'], diff --git a/lms/djangoapps/django_comment_client/utils.py b/lms/djangoapps/django_comment_client/utils.py index b3a1626d22..e442225c4d 100644 --- a/lms/djangoapps/django_comment_client/utils.py +++ b/lms/djangoapps/django_comment_client/utils.py @@ -352,7 +352,7 @@ def safe_content(content): 'updated_at', 'depth', 'type', 'commentable_id', 'comments_count', 'at_position_list', 'children', 'highlighted_title', 'highlighted_body', 'courseware_title', 'courseware_url', 'tags', 'unread_comments_count', - 'read', + 'read', "abuse_flaggers", "spoiler_flaggers" ] if (content.get('anonymous') is False) and (content.get('anonymous_to_peers') is False): diff --git a/lms/static/coffee/src/discussion/content.coffee b/lms/static/coffee/src/discussion/content.coffee index 0e86064bf2..6a25a07ec2 100644 --- a/lms/static/coffee/src/discussion/content.coffee +++ b/lms/static/coffee/src/discussion/content.coffee @@ -84,6 +84,7 @@ if Backbone? urlMappers: 'retrieve' : -> DiscussionUtil.urlFor('retrieve_single_thread', @discussion.id, @id) 'reply' : -> DiscussionUtil.urlFor('create_comment', @id) + 'flagAbuse': -> DiscussionUtil.urlFor("flagAbuse_#{@get('type')}", @id) 'unvote' : -> DiscussionUtil.urlFor("undo_vote_for_#{@get('type')}", @id) 'upvote' : -> DiscussionUtil.urlFor("upvote_#{@get('type')}", @id) 'downvote' : -> DiscussionUtil.urlFor("downvote_#{@get('type')}", @id) @@ -113,6 +114,14 @@ if Backbone? unvote: -> @get("votes")["up_count"] = parseInt(@get("votes")["up_count"]) - 1 @trigger "change", @ + + flagAbuse: -> + @get("abuse_flaggers").push window.user.get('id') + @trigger "change", @ + + unflagAbuse: -> + @get("votes")["up_count"] = parseInt(@get("votes")["up_count"]) - 1 + @trigger "change", @ display_body: -> if @has("highlighted_body") diff --git a/lms/static/coffee/src/discussion/utils.coffee b/lms/static/coffee/src/discussion/utils.coffee index a032c0248f..6947eb6529 100644 --- a/lms/static/coffee/src/discussion/utils.coffee +++ b/lms/static/coffee/src/discussion/utils.coffee @@ -48,6 +48,7 @@ class @DiscussionUtil update_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/update" create_comment : "/courses/#{$$course_id}/discussion/threads/#{param}/reply" delete_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/delete" + flagAbuse_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/flagAbuse" upvote_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/upvote" downvote_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/downvote" undo_vote_for_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/unvote" diff --git a/lms/static/coffee/src/discussion/views/discussion_thread_show_view.coffee b/lms/static/coffee/src/discussion/views/discussion_thread_show_view.coffee index a8e95c2565..21458bcc39 100644 --- a/lms/static/coffee/src/discussion/views/discussion_thread_show_view.coffee +++ b/lms/static/coffee/src/discussion/views/discussion_thread_show_view.coffee @@ -3,6 +3,8 @@ if Backbone? events: "click .discussion-vote": "toggleVote" + "click .discussion-flag-abuse": "toggleFlagAbuse" + "click .discussion-flag-spoiler": "toggleFlagSpoiler" "click .action-follow": "toggleFollowing" "click .action-edit": "edit" "click .action-delete": "delete" @@ -57,6 +59,20 @@ if Backbone? else @vote() + toggleFlagAbuse: (event) -> + event.preventDefault() + if window.user in @model.get("abuse_flaggers") + @unFlagAbuse() + else + @flagAbuse() + + toggleFlagSpoiler: (event) -> + event.preventDefault() + if window.user in @model.abuse_flaggers + @unFlagAbuse() + else + @flagAbuse() + toggleFollowing: (event) -> $elem = $(event.target) url = null @@ -82,6 +98,16 @@ if Backbone? if textStatus == 'success' @model.set(response, {silent: true}) + flagAbuse: -> + url = @model.urlFor("flagAbuse") + DiscussionUtil.safeAjax + $elem: @$(".discussion-flag-abuse") + url: url + type: "POST" + success: (response, textStatus) => + if textStatus == 'success' + @model.set(response, {silent: true}) + unvote: -> window.user.unvote(@model) url = @model.urlFor("unvote") @@ -93,6 +119,17 @@ if Backbone? if textStatus == 'success' @model.set(response, {silent: true}) + unFlagAbuse: -> + window.user.unvote(@model) + url = @model.urlFor("unvote") + DiscussionUtil.safeAjax + $elem: @$(".discussion-vote") + url: url + type: "POST" + success: (response, textStatus) => + if textStatus == 'success' + @model.set(response, {silent: true}) + edit: (event) -> @trigger "thread:edit", event diff --git a/lms/templates/discussion/_underscore_templates.html b/lms/templates/discussion/_underscore_templates.html index 7c14e5af17..b37f9acfa0 100644 --- a/lms/templates/discussion/_underscore_templates.html +++ b/lms/templates/discussion/_underscore_templates.html @@ -28,8 +28,10 @@
+ ${'<%- votes["up_count"] %>'} - + + ${'<%- abuse_flaggers.length%>'} + + + ${'<%- spoiler_flaggers.length%>'}

${'<%- title %>'}

${"<% if (obj.username) { %>"}