diff --git a/lms/djangoapps/django_comment_client/base/views.py b/lms/djangoapps/django_comment_client/base/views.py
index ee293351c0..70396ba064 100644
--- a/lms/djangoapps/django_comment_client/base/views.py
+++ b/lms/djangoapps/django_comment_client/base/views.py
@@ -21,7 +21,6 @@ from django.contrib.auth.models import User
from mitxmako.shortcuts import render_to_response, render_to_string
from courseware.courses import get_course_with_access
-
from django_comment_client.utils import JsonResponse, JsonError, extract
from django_comment_client.permissions import check_permissions_by_view
@@ -282,7 +281,7 @@ def update_moderator_status(request, course_id, user_id):
'course_id': course_id,
'user': request.user,
'django_user': user,
- 'discussion_user': discussion_user.to_dict(),
+ 'profiled_user': discussion_user.to_dict(),
}
return JsonResponse({
'html': render_to_string('discussion/ajax_user_profile.html', context)
@@ -298,10 +297,13 @@ def search_similar_threads(request, course_id, commentable_id):
'text': text,
'commentable_id': commentable_id,
}
- result = cc.search_similar_threads(course_id, recursive=False, query_params=query_params)
- return JsonResponse(result)
+ threads = cc.search_similar_threads(course_id, recursive=False, query_params=query_params)
else:
- return JsonResponse([])
+ theads = []
+ context = { 'threads': map(utils.extend_content, threads) }
+ return JsonResponse({
+ 'html': render_to_string('discussion/_similar_posts.html', context)
+ })
@require_GET
def tags_autocomplete(request, course_id):
@@ -334,8 +336,8 @@ def upload(request, course_id):#ajax upload file to a question or answer
# check file type
f = request.FILES['file-upload']
file_extension = os.path.splitext(f.name)[1].lower()
- if not file_extension in settings.DISCUSSION_ALLOWED_UPLOAD_FILE_TYPES:
- file_types = "', '".join(settings.DISCUSSION_ALLOWED_UPLOAD_FILE_TYPES)
+ if not file_extension in cc_settings.ALLOWED_UPLOAD_FILE_TYPES:
+ file_types = "', '".join(cc_settings.ALLOWED_UPLOAD_FILE_TYPES)
msg = _("allowed file types are '%(file_types)s'") % \
{'file_types': file_types}
raise exceptions.PermissionDenied(msg)
@@ -354,15 +356,16 @@ def upload(request, course_id):#ajax upload file to a question or answer
# check file size
# byte
size = file_storage.size(new_file_name)
- if size > settings.ASKBOT_MAX_UPLOAD_FILE_SIZE:
+ if size > cc_settings.MAX_UPLOAD_FILE_SIZE:
file_storage.delete(new_file_name)
msg = _("maximum upload file size is %(file_size)sK") % \
- {'file_size': settings.ASKBOT_MAX_UPLOAD_FILE_SIZE}
+ {'file_size': cc_settings.MAX_UPLOAD_FILE_SIZE}
raise exceptions.PermissionDenied(msg)
except exceptions.PermissionDenied, e:
error = unicode(e)
except Exception, e:
+ print e
logging.critical(unicode(e))
error = _('Error uploading file. Please contact the site administrator. Thank you.')
diff --git a/lms/djangoapps/django_comment_client/forum/views.py b/lms/djangoapps/django_comment_client/forum/views.py
index 592cb0a1d2..eda574cb6e 100644
--- a/lms/djangoapps/django_comment_client/forum/views.py
+++ b/lms/djangoapps/django_comment_client/forum/views.py
@@ -83,7 +83,7 @@ def render_discussion(request, course_id, threads, *args, **kwargs):
'base_url': base_url,
'query_params': strip_blank(strip_none(extract(query_params, ['page', 'sort_key', 'sort_order', 'tags', 'text']))),
'annotated_content_info': json.dumps(annotated_content_info),
- 'discussion_data': json.dumps({ discussion_id: threads }),
+ 'discussion_data': json.dumps({ (discussion_id or user_id): threads })
}
context = dict(context.items() + query_params.items())
return render_to_string(template, context)
@@ -250,7 +250,10 @@ def user_profile(request, course_id, user_id):
content = render_user_discussion(request, course_id, threads, user_id=user_id, query_params=query_params)
if request.is_ajax():
- return utils.HtmlResponse(content)
+ return utils.JsonResponse({
+ 'html': content,
+ 'discussionData': threads,
+ })
else:
context = {
'course': course,
diff --git a/lms/djangoapps/django_comment_client/helpers.py b/lms/djangoapps/django_comment_client/helpers.py
index 779ae3c9ee..c35559255d 100644
--- a/lms/djangoapps/django_comment_client/helpers.py
+++ b/lms/djangoapps/django_comment_client/helpers.py
@@ -12,7 +12,7 @@ import urllib
import os
def pluralize(singular_term, count):
- if int(count) >= 2:
+ if int(count) >= 2 or int(count) == 0:
return singular_term + 's'
return singular_term
@@ -33,24 +33,10 @@ def include_mustache_templates():
file_contents = map(read_file, filter(valid_file_name, os.listdir(mustache_dir)))
return '\n'.join(map(wrap_in_tag, map(strip_file_name, file_contents)))
-def permalink(content):
- if content['type'] == 'thread':
- return reverse('django_comment_client.forum.views.single_thread',
- args=[content['course_id'], content['commentable_id'], content['id']])
- else:
- return reverse('django_comment_client.forum.views.single_thread',
- args=[content['course_id'], content['commentable_id'], content['thread_id']]) + '#' + content['id']
-
def render_content(content, additional_context={}):
- content_info = {
- 'displayed_title': content.get('highlighted_title') or content.get('title', ''),
- 'displayed_body': content.get('highlighted_body') or content.get('body', ''),
- 'raw_tags': ','.join(content.get('tags', [])),
- 'permalink': permalink(content),
- }
context = {
- 'content': merge_dict(content, content_info),
+ 'content': extend_content(content),
content['type']: True,
}
context = merge_dict(context, additional_context)
diff --git a/lms/djangoapps/django_comment_client/mustache_helpers.py b/lms/djangoapps/django_comment_client/mustache_helpers.py
index 1961bf5c90..6f04ca527c 100644
--- a/lms/djangoapps/django_comment_client/mustache_helpers.py
+++ b/lms/djangoapps/django_comment_client/mustache_helpers.py
@@ -7,7 +7,8 @@ import inspect
def pluralize(content, text):
num, word = text.split(' ')
- if int(num or '0') >= 2:
+ num = int(num or '0')
+ if num >= 2 or num == 0:
return word + 's'
else:
return word
diff --git a/lms/djangoapps/django_comment_client/settings.py b/lms/djangoapps/django_comment_client/settings.py
new file mode 100644
index 0000000000..3234c32478
--- /dev/null
+++ b/lms/djangoapps/django_comment_client/settings.py
@@ -0,0 +1,10 @@
+from django.conf import settings
+
+MAX_COMMENT_DEPTH = None
+MAX_UPLOAD_FILE_SIZE = 1024 * 1024 #result in bytes
+ALLOWED_UPLOAD_FILE_TYPES = ('.jpg', '.jpeg', '.gif', '.bmp', '.png', '.tiff')
+
+if hasattr(settings, 'DISCUSSION_SETTINGS'):
+ MAX_COMMENT_DEPTH = settings.DISCUSSION_SETTINGS.get('MAX_COMMENT_DEPTH')
+ MAX_UPLOAD_FILE_SIZE = settings.DISCUSSION_SETTINGS.get('MAX_UPLOAD_FILE_SIZE') or MAX_UPLOAD_FILE_SIZE
+ ALLOWED_UPLOAD_FILE_TYPES = settings.DISCUSSION_SETTINGS.get('ALLOWED_UPLOAD_FILE_TYPES') or ALLOWED_UPLOAD_FILE_TYPES
diff --git a/lms/djangoapps/django_comment_client/utils.py b/lms/djangoapps/django_comment_client/utils.py
index 9e2f9c8a03..11403bbaed 100644
--- a/lms/djangoapps/django_comment_client/utils.py
+++ b/lms/djangoapps/django_comment_client/utils.py
@@ -197,3 +197,20 @@ def url_for_tags(course_id, tags):
def render_mustache(template_name, dictionary, *args, **kwargs):
template = middleware.lookup['main'].get_template(template_name).source
return pystache.render(template, dictionary)
+
+def permalink(content):
+ if content['type'] == 'thread':
+ return reverse('django_comment_client.forum.views.single_thread',
+ args=[content['course_id'], content['commentable_id'], content['id']])
+ else:
+ return reverse('django_comment_client.forum.views.single_thread',
+ args=[content['course_id'], content['commentable_id'], content['thread_id']]) + '#' + content['id']
+
+def extend_content(content):
+ content_info = {
+ 'displayed_title': content.get('highlighted_title') or content.get('title', ''),
+ 'displayed_body': content.get('highlighted_body') or content.get('body', ''),
+ 'raw_tags': ','.join(content.get('tags', [])),
+ 'permalink': permalink(content),
+ }
+ return merge_dict(content, content_info)
diff --git a/lms/static/coffee/src/discussion/content.coffee b/lms/static/coffee/src/discussion/content.coffee
index d427a348b3..9f2cec290b 100644
--- a/lms/static/coffee/src/discussion/content.coffee
+++ b/lms/static/coffee/src/discussion/content.coffee
@@ -1,410 +1,399 @@
-class @Content extends Backbone.Model
+if Backbone?
+ class @Content extends Backbone.Model
- template: -> DiscussionUtil.getTemplate('_content')
+ template: -> DiscussionUtil.getTemplate('_content')
- actions:
- editable: '.admin-edit'
- can_reply: '.discussion-reply'
- can_endorse: '.admin-endorse'
- can_delete: '.admin-delete'
- can_openclose: '.admin-openclose'
-
- urlMappers: {}
+ actions:
+ editable: '.admin-edit'
+ can_reply: '.discussion-reply'
+ can_endorse: '.admin-endorse'
+ can_delete: '.admin-delete'
+ can_openclose: '.admin-openclose'
+
+ urlMappers: {}
- urlFor: (name) ->
- @urlMappers[name].apply(@)
+ urlFor: (name) ->
+ @urlMappers[name].apply(@)
- can: (action) ->
- DiscussionUtil.getContentInfo @id, action
+ can: (action) ->
+ DiscussionUtil.getContentInfo @id, action
- updateInfo: (info) ->
- @set('ability', info.ability)
- @set('voted', info.voted)
- @set('subscribed', info.subscribed)
+ updateInfo: (info) ->
+ @set('ability', info.ability)
+ @set('voted', info.voted)
+ @set('subscribed', info.subscribed)
- addComment: (comment, options) ->
- options ||= {}
- if not options.silent
+ addComment: (comment, options) ->
+ options ||= {}
+ if not options.silent
+ thread = @get('thread')
+ comments_count = parseInt(thread.get('comments_count'))
+ thread.set('comments_count', comments_count + 1)
+ @get('children').push comment
+ model = new Comment $.extend {}, comment, { thread: @get('thread') }
+ @get('comments').add model
+ model
+
+ removeComment: (comment) ->
thread = @get('thread')
comments_count = parseInt(thread.get('comments_count'))
- thread.set('comments_count', comments_count + 1)
- @get('children').push comment
- model = new Comment $.extend {}, comment, { thread: @get('thread') }
- @get('comments').add model
- model
+ thread.set('comments_count', comments_count - 1 - comment.getCommentsCount())
- removeComment: (comment) ->
- thread = @get('thread')
- comments_count = parseInt(thread.get('comments_count'))
- thread.set('comments_count', comments_count - 1 - comment.getCommentsCount())
+ resetComments: (children) ->
+ @set 'children', []
+ @set 'comments', new Comments()
+ for comment in (children || [])
+ @addComment comment, { silent: true }
- resetComments: (children) ->
- @set 'children', []
- @set 'comments', new Comments()
- for comment in (children || [])
- @addComment comment, { silent: true }
-
- initialize: ->
- DiscussionUtil.addContent @id, @
- @resetComments(@get('children'))
-
-
-class @ContentView extends Backbone.View
-
- $: (selector) ->
- @$local.find(selector)
-
- partial:
- endorsed: (endorsed) ->
- if endorsed
- @$el.addClass("endorsed")
- else
- @$el.removeClass("endorsed")
-
- closed: (closed) -> # we should just re-render the whole thread, or update according to new abilities
- if closed
- @$el.addClass("closed")
- @$(".admin-openclose").text "Re-open Thread"
- else
- @$el.removeClass("closed")
- @$(".admin-openclose").text "Close Thread"
-
- voted: (voted) ->
- @$(".discussion-vote-up").removeClass("voted") if voted != "up"
- @$(".discussion-vote-down").removeClass("voted") if voted != "down"
- @$(".discussion-vote-#{voted}").addClass("voted") if voted in ["up", "down"]
-
- votes_point: (votes_point) ->
- @$(".discussion-votes-point").html(votes_point)
-
- comments_count: (comments_count) ->
- @$(".comments-count").html(comments_count)
+ initialize: ->
+ DiscussionUtil.addContent @id, @
+ @resetComments(@get('children'))
- subscribed: (subscribed) ->
- if subscribed
- @$(".discussion-follow-thread").addClass("discussion-unfollow-thread").html("Unfollow")
+
+ class @ContentView extends Backbone.View
+
+ $: (selector) ->
+ @$local.find(selector)
+
+ partial:
+ endorsed: (endorsed) ->
+ if endorsed
+ @$el.addClass("endorsed")
+ else
+ @$el.removeClass("endorsed")
+
+ closed: (closed) -> # we should just re-render the whole thread, or update according to new abilities
+ if closed
+ @$el.addClass("closed")
+ @$(".admin-openclose").text "Re-open Thread"
+ else
+ @$el.removeClass("closed")
+ @$(".admin-openclose").text "Close Thread"
+
+ voted: (voted) ->
+ @$(".discussion-vote-up").removeClass("voted") if voted != "up"
+ @$(".discussion-vote-down").removeClass("voted") if voted != "down"
+ @$(".discussion-vote-#{voted}").addClass("voted") if voted in ["up", "down"]
+
+ votes_point: (votes_point) ->
+ @$(".discussion-votes-point").html(votes_point)
+
+ comments_count: (comments_count) ->
+ @$(".comments-count").html(comments_count)
+
+ subscribed: (subscribed) ->
+ if subscribed
+ @$(".discussion-follow-thread").addClass("discussion-unfollow-thread").html("Unfollow")
+ else
+ @$(".discussion-follow-thread").removeClass("discussion-unfollow-thread").html("Follow")
+
+ ability: (ability) ->
+ for action, elemSelector of @model.actions
+ if not ability[action]
+ @$(elemSelector).parent().remove()
+
+ $discussionContent: ->
+ @_discussionContent ||= @$el.children(".discussion-content")
+
+ $showComments: ->
+ @_showComments ||= @$(".discussion-show-comments")
+
+ updateShowComments: ->
+ if @showed
+ @$showComments().html @$showComments().html().replace "Show", "Hide"
else
- @$(".discussion-follow-thread").removeClass("discussion-unfollow-thread").html("Follow")
+ @$showComments().html @$showComments().html().replace "Hide", "Show"
- ability: (ability) ->
- for action, elemSelector of @model.actions
- if not ability[action]
- @$(elemSelector).parent().remove()
-
- $discussionContent: ->
- @_discussionContent ||= @$el.children(".discussion-content")
-
- $showComments: ->
- @_showComments ||= @$(".discussion-show-comments")
-
- updateShowComments: ->
- if @showed
- @$showComments().html @$showComments().html().replace "Show", "Hide"
- else
- @$showComments().html @$showComments().html().replace "Hide", "Show"
-
- retrieved: ->
- @$showComments().hasClass("retrieved")
-
- hideSingleThread: (event) ->
- @$el.children(".comments").hide()
- @showed = false
- @updateShowComments()
-
- showSingleThread: (event) ->
- if @retrieved()
- @$el.children(".comments").show()
- @showed = true
+ retrieved: ->
+ @$showComments().hasClass("retrieved")
+
+ hideSingleThread: (event) ->
+ @$el.children(".comments").hide()
+ @showed = false
@updateShowComments()
- else
- $elem = $.merge @$(".thread-title"), @$showComments()
- url = @model.urlFor('retrieve')
- DiscussionUtil.get $elem, url, {}, (response, textStatus) =>
+
+ showSingleThread: (event) ->
+ if @retrieved()
+ @$el.children(".comments").show()
@showed = true
@updateShowComments()
- @$showComments().addClass("retrieved")
- @$el.children(".comments").replaceWith response.html
- @model.resetComments response.content.children
- @initCommentViews()
- DiscussionUtil.bulkUpdateContentInfo response.annotated_content_info
-
- toggleSingleThread: (event) ->
- if @showed
- @hideSingleThread(event)
- else
- @showSingleThread(event)
-
- initCommentViews: ->
- @$el.children(".comments").children(".comment").each (index, elem) =>
- model = @model.get('comments').find $(elem).attr("_id")
- if not model.view
- commentView = new CommentView el: elem, model: model
-
- reply: ->
- if @model.get('type') == 'thread'
- @showSingleThread()
- $replyView = @$(".discussion-reply-new")
- if $replyView.length
- $replyView.show()
- else
- view = {}
- view.id = @model.id
- view.showWatchCheckbox = not @model.get('thread').get('subscribed')
- html = Mustache.render DiscussionUtil.getTemplate('_reply'), view
- @$discussionContent().append html
- DiscussionUtil.makeWmdEditor @$el, $.proxy(@$, @), "reply-body"
- @$(".discussion-submit-post").click $.proxy(@submitReply, @)
- @$(".discussion-cancel-post").click $.proxy(@cancelReply, @)
- @$(".discussion-reply").hide()
- @$(".discussion-edit").hide()
-
- submitReply: (event) ->
- url = @model.urlFor('reply')
-
- body = DiscussionUtil.getWmdContent @$el, $.proxy(@$, @), "reply-body"
-
- anonymous = false || @$(".discussion-post-anonymously").is(":checked")
- autowatch = false || @$(".discussion-auto-watch").is(":checked")
-
- DiscussionUtil.safeAjax
- $elem: $(event.target)
- url: url
- type: "POST"
- dataType: 'json'
- data:
- body: body
- anonymous: anonymous
- auto_subscribe: autowatch
- error: DiscussionUtil.formErrorHandler @$(".discussion-errors")
- success: (response, textStatus) =>
- DiscussionUtil.clearFormErrors @$(".discussion-errors")
- $comment = $(response.html)
- @$el.children(".comments").prepend $comment
- DiscussionUtil.setWmdContent @$el, $.proxy(@$, @), "reply-body", ""
- comment = @model.addComment response.content
- commentView = new CommentView el: $comment[0], model: comment
- comment.updateInfo response.annotated_content_info
- @cancelReply()
-
- cancelReply: ->
- $replyView = @$(".discussion-reply-new")
- if $replyView.length
- $replyView.hide()
- @$(".discussion-reply").show()
- @$(".discussion-edit").show()
-
- unvote: (event) ->
- url = @model.urlFor('unvote')
- $elem = @$(".discussion-vote")
- DiscussionUtil.post $elem, url, {}, (response, textStatus) =>
- @model.set('voted', '')
- @model.set('votes_point', response.votes.point)
-
- vote: (event, value) ->
- url = @model.urlFor("#{value}vote")
- $elem = @$(".discussion-vote")
- DiscussionUtil.post $elem, url, {}, (response, textStatus) =>
- @model.set('voted', value)
- @model.set('votes_point', response.votes.point)
-
- toggleVote: (event) ->
- $elem = $(event.target)
- value = $elem.attr("value")
- if @model.get("voted") == value
- @unvote(event)
- else
- @vote(event, value)
-
- toggleEndorse: (event) ->
- $elem = $(event.target)
- url = @model.urlFor('endorse')
- endorsed = @model.get('endorsed')
- data = { endorsed: not endorsed }
- DiscussionUtil.post $elem, url, data, (response, textStatus) =>
- @model.set('endorsed', not endorsed)
-
- toggleFollow: (event) ->
- $elem = $(event.target)
- subscribed = @model.get('subscribed')
- if subscribed
- url = @model.urlFor('unfollow')
- else
- url = @model.urlFor('follow')
- DiscussionUtil.post $elem, url, {}, (response, textStatus) =>
- @model.set('subscribed', not subscribed)
-
- toggleClosed: (event) ->
- $elem = $(event.target)
- url = @model.urlFor('close')
- closed = @model.get('closed')
- data = { closed: not closed }
- DiscussionUtil.post $elem, url, data, (response, textStatus) =>
- @model.set('closed', not closed)
-
- edit: (event) ->
- @$(".discussion-content-wrapper").hide()
- $editView = @$(".discussion-content-edit")
- if $editView.length
- $editView.show()
- else
- view = {}
- view.id = @model.id
- if @model.get('type') == 'thread'
- view.title = @$(".thread-raw-title").html()
- view.body = @$(".thread-raw-body").html()
- view.tags = @$(".thread-raw-tags").html()
else
- view.body = @$(".comment-raw-body").html()
- @$discussionContent().append Mustache.render DiscussionUtil.getTemplate("_edit_#{@model.get('type')}"), view
- Discussion.makeWmdEditor @$el, $.proxy(@$, @), "#{@model.get('type')}-body-edit"
- @$(".thread-tags-edit").tagsInput DiscussionUtil.tagsInputOptions()
- @$(".discussion-submit-update").unbind("click").click $.proxy(@submitEdit, @)
- @$(".discussion-cancel-update").unbind("click").click $.proxy(@cancelEdit, @)
+ $elem = $.merge @$(".thread-title"), @$showComments()
+ url = @model.urlFor('retrieve')
+ DiscussionUtil.get $elem, url, {}, (response, textStatus) =>
+ @showed = true
+ @updateShowComments()
+ @$showComments().addClass("retrieved")
+ @$el.children(".comments").replaceWith response.html
+ @model.resetComments response.content.children
+ @initCommentViews()
+ DiscussionUtil.bulkUpdateContentInfo response.annotated_content_info
- submitEdit: (event) ->
+ toggleSingleThread: (event) ->
+ if @showed
+ @hideSingleThread(event)
+ else
+ @showSingleThread(event)
+
+ initCommentViews: ->
+ @$el.children(".comments").children(".comment").each (index, elem) =>
+ model = @model.get('comments').find $(elem).attr("_id")
+ if not model.view
+ commentView = new CommentView el: elem, model: model
- url = @model.urlFor('update')
- data = {}
- if @model.get('type') == 'thread'
- data.title = @$(".thread-title-edit").val()
- data.body = DiscussionUtil.getWmdContent @$el, $.proxy(@$, @), "thread-body-edit"
- data.tags = @$(".thread-tags-edit").val()
- else
- data.body = DiscussionUtil.getWmdContent @$el, $.proxy(@$, @), "comment-body-edit"
- DiscussionUtil.safeAjax
- $elem: $(event.target)
- url: url
- type: "POST"
- dataType: 'json'
- data: data
- error: DiscussionUtil.formErrorHandler @$(".discussion-update-errors")
- success: (response, textStatus) =>
- DiscussionUtil.clearFormErrors @$(".discussion-update-errors")
- @$discussionContent().replaceWith(response.html)
- @model.set response.content
- @model.updateInfo response.annotated_content_info
+ reply: ->
+ if @model.get('type') == 'thread'
+ @showSingleThread()
+ $replyView = @$(".discussion-reply-new")
+ if $replyView.length
+ $replyView.show()
+ else
+ view = {}
+ view.id = @model.id
+ view.showWatchCheckbox = not @model.get('thread').get('subscribed')
+ html = Mustache.render DiscussionUtil.getTemplate('_reply'), view
+ @$discussionContent().append html
+ DiscussionUtil.makeWmdEditor @$el, $.proxy(@$, @), "reply-body"
+ @$(".discussion-submit-post").click $.proxy(@submitReply, @)
+ @$(".discussion-cancel-post").click $.proxy(@cancelReply, @)
+ @$(".discussion-reply").hide()
+ @$(".discussion-edit").hide()
- cancelEdit: (event) ->
- @$(".discussion-content-edit").hide()
- @$(".discussion-content-wrapper").show()
+ submitReply: (event) ->
+ url = @model.urlFor('reply')
- delete: (event) ->
- url = @model.urlFor('delete')
- if @model.get('type') == 'thread'
- c = confirm "Are you sure to delete thread \"#{@model.get('title')}\"?"
- else
- c = confirm "Are you sure to delete this comment? "
- if not c
- return
- $elem = $(event.target)
- DiscussionUtil.post $elem, url, {}, (response, textStatus) =>
- @$el.remove()
- @model.get('thread').removeComment(@model)
+ body = DiscussionUtil.getWmdContent @$el, $.proxy(@$, @), "reply-body"
+
+ anonymous = false || @$(".discussion-post-anonymously").is(":checked")
+ autowatch = false || @$(".discussion-auto-watch").is(":checked")
+
+ DiscussionUtil.safeAjax
+ $elem: $(event.target)
+ url: url
+ type: "POST"
+ dataType: 'json'
+ data:
+ body: body
+ anonymous: anonymous
+ auto_subscribe: autowatch
+ error: DiscussionUtil.formErrorHandler @$(".discussion-errors")
+ success: (response, textStatus) =>
+ DiscussionUtil.clearFormErrors @$(".discussion-errors")
+ $comment = $(response.html)
+ @$el.children(".comments").prepend $comment
+ DiscussionUtil.setWmdContent @$el, $.proxy(@$, @), "reply-body", ""
+ comment = @model.addComment response.content
+ commentView = new CommentView el: $comment[0], model: comment
+ comment.updateInfo response.annotated_content_info
+ @cancelReply()
+
+ cancelReply: ->
+ $replyView = @$(".discussion-reply-new")
+ if $replyView.length
+ $replyView.hide()
+ @$(".discussion-reply").show()
+ @$(".discussion-edit").show()
+
+ unvote: (event) ->
+ url = @model.urlFor('unvote')
+ $elem = @$(".discussion-vote")
+ DiscussionUtil.post $elem, url, {}, (response, textStatus) =>
+ @model.set('voted', '')
+ @model.set('votes_point', response.votes.point)
+
+ vote: (event, value) ->
+ url = @model.urlFor("#{value}vote")
+ $elem = @$(".discussion-vote")
+ DiscussionUtil.post $elem, url, {}, (response, textStatus) =>
+ @model.set('voted', value)
+ @model.set('votes_point', response.votes.point)
+
+ toggleVote: (event) ->
+ $elem = $(event.target)
+ value = $elem.attr("value")
+ if @model.get("voted") == value
+ @unvote(event)
+ else
+ @vote(event, value)
+
+ toggleEndorse: (event) ->
+ $elem = $(event.target)
+ url = @model.urlFor('endorse')
+ endorsed = @model.get('endorsed')
+ data = { endorsed: not endorsed }
+ DiscussionUtil.post $elem, url, data, (response, textStatus) =>
+ @model.set('endorsed', not endorsed)
+
+ toggleFollow: (event) ->
+ $elem = $(event.target)
+ subscribed = @model.get('subscribed')
+ if subscribed
+ url = @model.urlFor('unfollow')
+ else
+ url = @model.urlFor('follow')
+ DiscussionUtil.post $elem, url, {}, (response, textStatus) =>
+ @model.set('subscribed', not subscribed)
+
+ toggleClosed: (event) ->
+ $elem = $(event.target)
+ url = @model.urlFor('close')
+ closed = @model.get('closed')
+ data = { closed: not closed }
+ DiscussionUtil.post $elem, url, data, (response, textStatus) =>
+ @model.set('closed', not closed)
+
+ edit: (event) ->
+ @$(".discussion-content-wrapper").hide()
+ $editView = @$(".discussion-content-edit")
+ if $editView.length
+ $editView.show()
+ else
+ view = {}
+ view.id = @model.id
+ if @model.get('type') == 'thread'
+ view.title = @$(".thread-raw-title").html()
+ view.body = @$(".thread-raw-body").html()
+ view.tags = @$(".thread-raw-tags").html()
+ else
+ view.body = @$(".comment-raw-body").html()
+ @$discussionContent().append Mustache.render DiscussionUtil.getTemplate("_edit_#{@model.get('type')}"), view
+ DiscussionUtil.makeWmdEditor @$el, $.proxy(@$, @), "#{@model.get('type')}-body-edit"
+ @$(".thread-tags-edit").tagsInput DiscussionUtil.tagsInputOptions()
+ @$(".discussion-submit-update").unbind("click").click $.proxy(@submitEdit, @)
+ @$(".discussion-cancel-update").unbind("click").click $.proxy(@cancelEdit, @)
+
+ submitEdit: (event) ->
+
+ url = @model.urlFor('update')
+ data = {}
+ if @model.get('type') == 'thread'
+ data.title = @$(".thread-title-edit").val()
+ data.body = DiscussionUtil.getWmdContent @$el, $.proxy(@$, @), "thread-body-edit"
+ data.tags = @$(".thread-tags-edit").val()
+ else
+ data.body = DiscussionUtil.getWmdContent @$el, $.proxy(@$, @), "comment-body-edit"
+ DiscussionUtil.safeAjax
+ $elem: $(event.target)
+ url: url
+ type: "POST"
+ dataType: 'json'
+ data: data
+ error: DiscussionUtil.formErrorHandler @$(".discussion-update-errors")
+ success: (response, textStatus) =>
+ DiscussionUtil.clearFormErrors @$(".discussion-update-errors")
+ @$discussionContent().replaceWith(response.html)
+ @model.set response.content
+ @model.updateInfo response.annotated_content_info
+
+ cancelEdit: (event) ->
+ @$(".discussion-content-edit").hide()
+ @$(".discussion-content-wrapper").show()
+
+ delete: (event) ->
+ url = @model.urlFor('delete')
+ if @model.get('type') == 'thread'
+ c = confirm "Are you sure to delete thread \"#{@model.get('title')}\"?"
+ else
+ c = confirm "Are you sure to delete this comment? "
+ if not c
+ return
+ $elem = $(event.target)
+ DiscussionUtil.post $elem, url, {}, (response, textStatus) =>
+ @$el.remove()
+ @model.get('thread').removeComment(@model)
+
+ events:
+ "click .discussion-follow-thread": "toggleFollow"
+ "click .thread-title": "toggleSingleThread"
+ "click .discussion-show-comments": "toggleSingleThread"
+ "click .discussion-reply-thread": "reply"
+ "click .discussion-reply-comment": "reply"
+ "click .discussion-cancel-reply": "cancelReply"
+ "click .discussion-vote-up": "toggleVote"
+ "click .discussion-vote-down": "toggleVote"
+ "click .admin-endorse": "toggleEndorse"
+ "click .admin-openclose": "toggleClosed"
+ "click .admin-edit": "edit"
+ "click .admin-delete": "delete"
+
+ initLocal: ->
+ @$local = @$el.children(".local")
+ @$delegateElement = @$local
+
+ initTitle: ->
+ $contentTitle = @$(".thread-title")
+ if $contentTitle.length
+ $contentTitle.html DiscussionUtil.unescapeHighlightTag DiscussionUtil.stripLatexHighlight $contentTitle.html()
+
+ initBody: ->
+ $contentBody = @$(".content-body")
+ $contentBody.html DiscussionUtil.postMathJaxProcessor DiscussionUtil.markdownWithHighlight $contentBody.html()
+ MathJax.Hub.Queue ["Typeset", MathJax.Hub, $contentBody.attr("id")]
+
+ initTimeago: ->
+ @$("span.timeago").timeago()
+
+ renderPartial: ->
+ for attr, value of @model.changedAttributes()
+ if @partial[attr]
+ @partial[attr].apply(@, [value])
+
+ initBindings: ->
+ @model.view = @
+ @model.bind('change', @renderPartial, @)
+
+ initialize: ->
+ @initBindings()
+ @initLocal()
+ @initTimeago()
+ @initTitle()
+ @initBody()
+ @initCommentViews()
- events:
- "click .discussion-follow-thread": "toggleFollow"
- "click .thread-title": "toggleSingleThread"
- "click .discussion-show-comments": "toggleSingleThread"
- "click .discussion-reply-thread": "reply"
- "click .discussion-reply-comment": "reply"
- "click .discussion-cancel-reply": "cancelReply"
- "click .discussion-vote-up": "toggleVote"
- "click .discussion-vote-down": "toggleVote"
- "click .admin-endorse": "toggleEndorse"
- "click .admin-openclose": "toggleClosed"
- "click .admin-edit": "edit"
- "click .admin-delete": "delete"
+ class @Thread extends @Content
+ urlMappers:
+ 'retrieve' : -> DiscussionUtil.urlFor('retrieve_single_thread', @discussion.id, @id)
+ 'reply' : -> DiscussionUtil.urlFor('create_comment', @id)
+ 'unvote' : -> DiscussionUtil.urlFor("undo_vote_for_#{@get('type')}", @id)
+ 'upvote' : -> DiscussionUtil.urlFor("upvote_#{@get('type')}", @id)
+ 'downvote' : -> DiscussionUtil.urlFor("downvote_#{@get('type')}", @id)
+ 'close' : -> DiscussionUtil.urlFor('openclose_thread', @id)
+ 'update' : -> DiscussionUtil.urlFor('update_thread', @id)
+ 'delete' : -> DiscussionUtil.urlFor('delete_thread', @id)
+ 'follow' : -> DiscussionUtil.urlFor('follow_thread', @id)
+ 'unfollow' : -> DiscussionUtil.urlFor('unfollow_thread', @id)
- initLocal: ->
- @$local = @$el.children(".local")
- @$delegateElement = @$local
+ initialize: ->
+ @set('thread', @)
+ super()
- initTitle: ->
- $contentTitle = @$(".thread-title")
- if $contentTitle.length
- $contentTitle.html DiscussionUtil.unescapeHighlightTag DiscussionUtil.stripLatexHighlight $contentTitle.html()
+ class @ThreadView extends @ContentView
- initBody: ->
- $contentBody = @$(".content-body")
- $contentBody.html DiscussionUtil.postMathJaxProcessor DiscussionUtil.markdownWithHighlight $contentBody.html()
- MathJax.Hub.Queue ["Typeset", MathJax.Hub, $contentBody.attr("id")]
+ class @Comment extends @Content
+ urlMappers:
+ 'reply': -> DiscussionUtil.urlFor('create_sub_comment', @id)
+ 'unvote': -> DiscussionUtil.urlFor("undo_vote_for_#{@get('type')}", @id)
+ 'upvote': -> DiscussionUtil.urlFor("upvote_#{@get('type')}", @id)
+ 'downvote': -> DiscussionUtil.urlFor("downvote_#{@get('type')}", @id)
+ 'endorse': -> DiscussionUtil.urlFor('endorse_comment', @id)
+ 'update': -> DiscussionUtil.urlFor('update_comment', @id)
+ 'delete': -> DiscussionUtil.urlFor('delete_comment', @id)
- initTimeago: ->
- @$("span.timeago").timeago()
+ getCommentsCount: ->
+ count = 0
+ @get('comments').each (comment) ->
+ count += comment.getCommentsCount() + 1
+ count
- initPermalink: ->
- @$(".discussion-permanent-link").attr "href", @model.permalink()
+ class @CommentView extends @ContentView
- renderPartial: ->
- for attr, value of @model.changedAttributes()
- if @partial[attr]
- @partial[attr].apply(@, [value])
+ class @Comments extends Backbone.Collection
- initBindings: ->
- @model.view = @
- @model.bind('change', @renderPartial, @)
+ model: Comment
- initialize: ->
- @initBindings()
- @initLocal()
- @initTimeago()
- @initTitle()
- @initBody()
- @initCommentViews()
-
-class @Thread extends @Content
- urlMappers:
- 'retrieve' : -> DiscussionUtil.urlFor('retrieve_single_thread', @discussion.id, @id)
- 'reply' : -> DiscussionUtil.urlFor('create_comment', @id)
- 'unvote' : -> DiscussionUtil.urlFor("undo_vote_for_#{@get('type')}", @id)
- 'upvote' : -> DiscussionUtil.urlFor("upvote_#{@get('type')}", @id)
- 'downvote' : -> DiscussionUtil.urlFor("downvote_#{@get('type')}", @id)
- 'close' : -> DiscussionUtil.urlFor('openclose_thread', @id)
- 'update' : -> DiscussionUtil.urlFor('update_thread', @id)
- 'delete' : -> DiscussionUtil.urlFor('delete_thread', @id)
- 'follow' : -> DiscussionUtil.urlFor('follow_thread', @id)
- 'unfollow' : -> DiscussionUtil.urlFor('unfollow_thread', @id)
+ initialize: ->
+ @bind "add", (item) =>
+ item.collection = @
- initialize: ->
- @set('thread', @)
- super()
-
- permalink: ->
- discussion_id = @get('commentable_id')
- return Discussion.urlFor("permanent_link_thread", discussion_id, @id)
-
-class @ThreadView extends @ContentView
-
-class @Comment extends @Content
- urlMappers:
- 'reply': -> DiscussionUtil.urlFor('create_sub_comment', @id)
- 'unvote': -> DiscussionUtil.urlFor("undo_vote_for_#{@get('type')}", @id)
- 'upvote': -> DiscussionUtil.urlFor("upvote_#{@get('type')}", @id)
- 'downvote': -> DiscussionUtil.urlFor("downvote_#{@get('type')}", @id)
- 'endorse': -> DiscussionUtil.urlFor('endorse_comment', @id)
- 'update': -> DiscussionUtil.urlFor('update_comment', @id)
- 'delete': -> DiscussionUtil.urlFor('delete_comment', @id)
-
- permalink: ->
- thread_id = @get('thread').id
- discussion_id = @get('thread').get('commentable_id')
- return Discussion.urlFor("permanent_link_comment", discussion_id, thread_id, @id)
-
- getCommentsCount: ->
- count = 0
- @get('comments').each (comment) ->
- count += comment.getCommentsCount() + 1
- count
-
-class @CommentView extends @ContentView
-
-class @Comments extends Backbone.Collection
-
- model: Comment
-
- initialize: ->
- @bind "add", (item) =>
- item.collection = @
-
- find: (id) ->
- _.first @where(id: id)
+ find: (id) ->
+ _.first @where(id: id)
diff --git a/lms/static/coffee/src/discussion/discussion.coffee b/lms/static/coffee/src/discussion/discussion.coffee
index 04eed9bf9c..4014526f1d 100644
--- a/lms/static/coffee/src/discussion/discussion.coffee
+++ b/lms/static/coffee/src/discussion/discussion.coffee
@@ -1,167 +1,172 @@
-class @Discussion extends Backbone.Collection
- model: Thread
+if Backbone?
+ class @Discussion extends Backbone.Collection
+ model: Thread
- initialize: ->
- DiscussionUtil.addDiscussion @id, @
- @bind "add", (item) =>
- item.discussion = @
+ initialize: ->
+ DiscussionUtil.addDiscussion @id, @
+ @bind "add", (item) =>
+ item.discussion = @
- find: (id) ->
- _.first @where(id: id)
+ find: (id) ->
+ _.first @where(id: id)
- addThread: (thread, options) ->
- options ||= {}
- model = new Thread thread
- @add model
- model
+ addThread: (thread, options) ->
+ options ||= {}
+ model = new Thread thread
+ @add model
+ model
-class @DiscussionView extends Backbone.View
+ class @DiscussionView extends Backbone.View
- $: (selector) ->
- @$local.find(selector)
+ $: (selector) ->
+ @$local.find(selector)
- initLocal: ->
- @$local = @$el.children(".local")
- @$delegateElement = @$local
+ initLocal: ->
+ @$local = @$el.children(".local")
+ @$delegateElement = @$local
- initialize: ->
- @initLocal()
- @model.id = @$el.attr("_id")
- @model.view = @
- @$el.children(".threads").children(".thread").each (index, elem) =>
- threadView = new ThreadView el: elem, model: @model.find $(elem).attr("_id")
- if @$el.hasClass("forum-discussion")
- $(".discussion-sidebar").find(".sidebar-new-post-button")
- .unbind('click').click $.proxy @newPost, @
- else if @$el.hasClass("inline-discussion")
- @newPost()
+ initialize: ->
+ @initLocal()
+ @model.id = @$el.attr("_id")
+ @model.view = @
+ @$el.children(".threads").children(".thread").each (index, elem) =>
+ threadView = new ThreadView el: elem, model: @model.find $(elem).attr("_id")
+ if @$el.hasClass("forum-discussion")
+ $(".discussion-sidebar").find(".sidebar-new-post-button")
+ .unbind('click').click $.proxy @newPost, @
+ else if @$el.hasClass("inline-discussion")
+ @newPost()
- reload: ($elem, url) ->
- if not url then return
- DiscussionUtil.get $elem, url, {}, (response, textStatus) =>
- $parent = @$el.parent()
- @$el.replaceWith(response.html)
- $discussion = $parent.find("section.discussion")
- @model.reset(response.discussionData, { silent: false })
- view = new DiscussionView el: $discussion[0], model: @model
- DiscussionUtil.bulkUpdateContentInfo(window.$$annotated_content_info)
+ reload: ($elem, url) ->
+ if not url then return
+ DiscussionUtil.get $elem, url, {}, (response, textStatus) =>
+ $parent = @$el.parent()
+ @$el.replaceWith(response.html)
+ $discussion = $parent.find("section.discussion")
+ @model.reset(response.discussionData, { silent: false })
+ view = new DiscussionView el: $discussion[0], model: @model
+ DiscussionUtil.bulkUpdateContentInfo(window.$$annotated_content_info)
+ $("html, body").animate({ scrollTop: 0 }, 0)
- loadSimilarPost: (event) ->
- $title = @$(".new-post-title")
- $wrapper = @$(".new-post-similar-posts-wrapper")
- $similarPosts = @$(".new-post-similar-posts")
- prevText = $title.attr("prev-text")
- text = $title.val()
- if text == prevText
- if @$(".similar-post").length
- $wrapper.show()
- else if $.trim(text).length
- $elem = $(event.target)
- url = DiscussionUtil.urlFor 'search_similar_threads', @model.id
- data = { text: @$(".new-post-title").val() }
- DiscussionUtil.get $elem, url, data, (response, textStatus) =>
- $similarPosts.empty()
- if $.type(response) == "array" and response.length
+ loadSimilarPost: (event) ->
+ console.log "loading similar"
+ $title = @$(".new-post-title")
+ $wrapper = @$(".new-post-similar-posts-wrapper")
+ $similarPosts = @$(".new-post-similar-posts")
+ prevText = $title.attr("prev-text")
+ text = $title.val()
+ if text == prevText
+ if @$(".similar-post").length
$wrapper.show()
- for thread in response
- $similarPost = $("").addClass("similar-post")
- .html(thread["title"])
- .attr("href", "javascript:void(0)") #TODO
- .appendTo($similarPosts)
- else
- $wrapper.hide()
- else
- $wrapper.hide()
- $title.attr("prev-text", text)
+ else if $.trim(text).length
+ $elem = $(event.target)
+ url = DiscussionUtil.urlFor 'search_similar_threads', @model.id
+ data = { text: @$(".new-post-title").val() }
+ DiscussionUtil.safeAjax
+ $elem: $elem
+ url: url
+ data: data
+ dataType: 'json'
+ success: (response, textStatus) =>
+ $wrapper.html(response.html)
+ if $wrapper.find(".similar-post").length
+ $wrapper.show()
+ $wrapper.find(".hide-similar-posts").click =>
+ $wrapper.hide()
+ else
+ $wrapper.hide()
+ $title.attr("prev-text", text)
- newPost: ->
- if not @$(".wmd-panel").length
- view = { discussion_id: @model.id }
- @$el.children(".discussion-non-content").append Mustache.render DiscussionUtil.getTemplate("_new_post"), view
- $newPostBody = @$(".new-post-body")
- DiscussionUtil.makeWmdEditor @$el, $.proxy(@$, @), "new-post-body"
+ newPost: ->
+ if not @$(".wmd-panel").length
+ view = { discussion_id: @model.id }
+ @$el.children(".discussion-non-content").append Mustache.render DiscussionUtil.getTemplate("_new_post"), view
+ $newPostBody = @$(".new-post-body")
+ DiscussionUtil.makeWmdEditor @$el, $.proxy(@$, @), "new-post-body"
- $input = DiscussionUtil.getWmdInput @$el, $.proxy(@$, @), "new-post-body"
- $input.attr("placeholder", "post a new topic...")
- if @$el.hasClass("inline-discussion")
- $input.bind 'focus', (e) =>
+ $input = DiscussionUtil.getWmdInput @$el, $.proxy(@$, @), "new-post-body"
+ $input.attr("placeholder", "post a new topic...")
+ if @$el.hasClass("inline-discussion")
+ $input.bind 'focus', (e) =>
+ @$(".new-post-form").removeClass('collapsed')
+ else if @$el.hasClass("forum-discussion")
@$(".new-post-form").removeClass('collapsed')
- else if @$el.hasClass("forum-discussion")
- @$(".new-post-form").removeClass('collapsed')
- @$(".new-post-tags").tagsInput DiscussionUtil.tagsInputOptions()
+ @$(".new-post-tags").tagsInput DiscussionUtil.tagsInputOptions()
- @$(".new-post-title").blur $.proxy(@loadSimilarPost, @)
+ @$(".new-post-title").blur $.proxy(@loadSimilarPost, @)
- @$(".hide-similar-posts").click =>
- @$(".new-post-similar-posts-wrapper").hide()
+ @$(".hide-similar-posts").click =>
+ @$(".new-post-similar-posts-wrapper").hide()
- @$(".discussion-submit-post").click $.proxy(@submitNewPost, @)
- @$(".discussion-cancel-post").click $.proxy(@cancelNewPost, @)
-
-
- @$(".new-post-form").show()
-
- submitNewPost: (event) ->
- title = @$(".new-post-title").val()
- body = DiscussionUtil.getWmdContent @$el, $.proxy(@$, @), "new-post-body"
- tags = @$(".new-post-tags").val()
- anonymous = false || @$(".discussion-post-anonymously").is(":checked")
- autowatch = false || @$(".discussion-auto-watch").is(":checked")
- url = DiscussionUtil.urlFor('create_thread', @model.id)
- DiscussionUtil.safeAjax
- $elem: $(event.target)
- url: url
- type: "POST"
- dataType: 'json'
- data:
- title: title
- body: body
- tags: tags
- anonymous: anonymous
- auto_subscribe: autowatch
- error: DiscussionUtil.formErrorHandler(@$(".new-post-form-errors"))
- success: (response, textStatus) =>
- DiscussionUtil.clearFormErrors(@$(".new-post-form-errors"))
- $thread = $(response.html)
- @$el.children(".threads").prepend($thread)
-
- @$(".new-post-title").val("")
- DiscussionUtil.setWmdContent @$el, $.proxy(@$, @), "new-post-body", ""
- @$(".new-post-tags").val("")
- @$(".new-post-tags").importTags("")
-
- thread = @model.addThread response.content
- threadView = new ThreadView el: $thread[0], model: thread
- thread.updateInfo response.annotated_content_info
- @cancelNewPost()
+ @$(".discussion-submit-post").click $.proxy(@submitNewPost, @)
+ @$(".discussion-cancel-post").click $.proxy(@cancelNewPost, @)
- cancelNewPost: (event) ->
- if @$el.hasClass("inline-discussion")
- @$(".new-post-form").addClass("collapsed")
- else if @$el.hasClass("forum-discussion")
- @$(".new-post-form").hide()
+ @$(".new-post-form").show()
- search: (event) ->
- event.preventDefault()
- $elem = $(event.target)
- url = URI($elem.attr("action")).addSearch({text: @$(".search-input").val()})
- @reload($elem, url)
+ submitNewPost: (event) ->
+ title = @$(".new-post-title").val()
+ body = DiscussionUtil.getWmdContent @$el, $.proxy(@$, @), "new-post-body"
+ tags = @$(".new-post-tags").val()
+ anonymous = false || @$(".discussion-post-anonymously").is(":checked")
+ autowatch = false || @$(".discussion-auto-watch").is(":checked")
+ url = DiscussionUtil.urlFor('create_thread', @model.id)
+ DiscussionUtil.safeAjax
+ $elem: $(event.target)
+ url: url
+ type: "POST"
+ dataType: 'json'
+ data:
+ title: title
+ body: body
+ tags: tags
+ anonymous: anonymous
+ auto_subscribe: autowatch
+ error: DiscussionUtil.formErrorHandler(@$(".new-post-form-errors"))
+ success: (response, textStatus) =>
+ DiscussionUtil.clearFormErrors(@$(".new-post-form-errors"))
+ $thread = $(response.html)
+ @$el.children(".threads").prepend($thread)
- sort: ->
- $elem = $(event.target)
- url = $elem.attr("sort-url")
- @reload($elem, url)
+ @$(".new-post-similar-posts").empty()
+ @$(".new-post-similar-posts-wrapper").hide()
+ @$(".new-post-title").val("").attr("prev-text", "")
+ DiscussionUtil.setWmdContent @$el, $.proxy(@$, @), "new-post-body", ""
+ @$(".new-post-tags").val("")
+ @$(".new-post-tags").importTags("")
- page: (event) ->
- $elem = $(event.target)
- url = $elem.attr("page-url")
- @reload($elem, url)
+ thread = @model.addThread response.content
+ threadView = new ThreadView el: $thread[0], model: thread
+ thread.updateInfo response.annotated_content_info
+ @cancelNewPost()
+
- events:
- "submit .search-wrapper>.discussion-search-form": "search"
- "click .discussion-search-link": "search"
- "click .discussion-sort-link": "sort"
- "click .discussion-page-link": "page"
+ cancelNewPost: (event) ->
+ if @$el.hasClass("inline-discussion")
+ @$(".new-post-form").addClass("collapsed")
+ else if @$el.hasClass("forum-discussion")
+ @$(".new-post-form").hide()
+
+ search: (event) ->
+ event.preventDefault()
+ $elem = $(event.target)
+ url = URI($elem.attr("action")).addSearch({text: @$(".search-input").val()})
+ @reload($elem, url)
+
+ sort: ->
+ $elem = $(event.target)
+ url = $elem.attr("sort-url")
+ @reload($elem, url)
+
+ page: (event) ->
+ $elem = $(event.target)
+ url = $elem.attr("page-url")
+ @reload($elem, url)
+
+ events:
+ "submit .search-wrapper>.discussion-search-form": "search"
+ "click .discussion-search-link": "search"
+ "click .discussion-sort-link": "sort"
+ "click .discussion-page-link": "page"
diff --git a/lms/static/coffee/src/discussion/discussion_module.coffee b/lms/static/coffee/src/discussion/discussion_module.coffee
index 38f44be1f1..6452d065d8 100644
--- a/lms/static/coffee/src/discussion/discussion_module.coffee
+++ b/lms/static/coffee/src/discussion/discussion_module.coffee
@@ -1,32 +1,33 @@
-class @DiscussionModuleView extends Backbone.View
- events:
- "click .discussion-show": "toggleDiscussion"
- toggleDiscussion: (event) ->
- if @showed
- @$("section.discussion").hide()
- $(event.target).html("Show Discussion")
- @showed = false
- else
- if @retrieved
- @$("section.discussion").show()
- $(event.target).html("Hide Discussion")
- @showed = true
+if Backbone?
+ class @DiscussionModuleView extends Backbone.View
+ events:
+ "click .discussion-show": "toggleDiscussion"
+ toggleDiscussion: (event) ->
+ if @showed
+ @$("section.discussion").hide()
+ $(event.target).html("Show Discussion")
+ @showed = false
else
- $elem = $(event.target)
- discussion_id = $elem.attr("discussion_id")
- url = DiscussionUtil.urlFor 'retrieve_discussion', discussion_id
- Discussion.safeAjax
- $elem: $elem
- url: url
- type: "GET"
- dataType: 'json'
- success: (response, textStatus) =>
- @$el.append(response.html)
- $discussion = @$el.find("section.discussion")
- $(event.target).html("Hide Discussion")
- discussion = new Discussion()
- discussion.reset(response.discussionData, {silent: false})
- view = new DiscussionView(el: $discussion[0], model: discussion)
- DiscussionUtil.bulkUpdateContentInfo(window.$$annotated_content_info)
- @retrieved = true
- @showed = true
+ if @retrieved
+ @$("section.discussion").show()
+ $(event.target).html("Hide Discussion")
+ @showed = true
+ else
+ $elem = $(event.target)
+ discussion_id = $elem.attr("discussion_id")
+ url = DiscussionUtil.urlFor 'retrieve_discussion', discussion_id
+ DiscussionUtil.safeAjax
+ $elem: $elem
+ url: url
+ type: "GET"
+ dataType: 'json'
+ success: (response, textStatus) =>
+ @$el.append(response.html)
+ $discussion = @$el.find("section.discussion")
+ $(event.target).html("Hide Discussion")
+ discussion = new Discussion()
+ discussion.reset(response.discussionData, {silent: false})
+ view = new DiscussionView(el: $discussion[0], model: discussion)
+ DiscussionUtil.bulkUpdateContentInfo(window.$$annotated_content_info)
+ @retrieved = true
+ @showed = true
diff --git a/lms/static/coffee/src/discussion/main.coffee b/lms/static/coffee/src/discussion/main.coffee
index 2266e136ed..023345c5da 100644
--- a/lms/static/coffee/src/discussion/main.coffee
+++ b/lms/static/coffee/src/discussion/main.coffee
@@ -12,4 +12,10 @@ $ ->
discussion.reset(discussionData, {silent: false})
view = new DiscussionView(el: elem, model: discussion)
- DiscussionUtil.bulkUpdateContentInfo(window.$$annotated_content_info)
+ if window.$$annotated_content_info?
+ DiscussionUtil.bulkUpdateContentInfo(window.$$annotated_content_info)
+
+ $userProfile = $(".discussion-sidebar>.user-profile")
+ if $userProfile.length
+ console.log "initialize user profile"
+ view = new DiscussionUserProfileView(el: $userProfile[0])
diff --git a/lms/static/coffee/src/discussion/user_profile.coffee b/lms/static/coffee/src/discussion/user_profile.coffee
index 0cff708ae6..ed4f6ea988 100644
--- a/lms/static/coffee/src/discussion/user_profile.coffee
+++ b/lms/static/coffee/src/discussion/user_profile.coffee
@@ -1,34 +1,29 @@
-if not @Discussion?
- @Discussion = {}
+class @DiscussionUserProfileView extends Backbone.View
+ toggleModeratorStatus: (event) ->
+ confirmValue = confirm("Are you sure?")
+ if not confirmValue then return
+ $elem = $(event.target)
+ if $elem.hasClass("sidebar-promote-moderator-button")
+ isModerator = true
+ else if $elem.hasClass("sidebar-revoke-moderator-button")
+ isModerator = false
+ else
+ console.error "unrecognized moderator status"
+ return
+ url = DiscussionUtil.urlFor('update_moderator_status', $$profiled_user_id)
+ DiscussionUtil.safeAjax
+ $elem: $elem
+ url: url
+ type: "POST"
+ dataType: 'json'
+ data:
+ is_moderator: isModerator
+ error: (response, textStatus, e) ->
+ console.log e
+ success: (response, textStatus) =>
+ parent = @$el.parent()
+ @$el.replaceWith(response.html)
+ view = new DiscussionUserProfileView el: parent.children(".user-profile")
-Discussion = @Discussion
-
-@Discussion = $.extend @Discussion,
- initializeUserProfile: ($userProfile) ->
- $local = Discussion.generateLocal $userProfile
-
- handleUpdateModeratorStatus = (elem, isModerator) ->
- confirmValue = confirm("Are you sure?")
- if not confirmValue then return
- url = Discussion.urlFor('update_moderator_status', $$profiled_user_id)
- Discussion.safeAjax
- $elem: $(elem)
- url: url
- type: "POST"
- dataType: 'json'
- data:
- is_moderator: isModerator
- error: (response, textStatus, e) ->
- console.log e
- success: (response, textStatus) ->
- parent = $userProfile.parent()
- $userProfile.replaceWith(response.html)
- Discussion.initializeUserProfile parent.children(".user-profile")
-
- Discussion.bindLocalEvents $local,
- "click .sidebar-revoke-moderator-button": (event) ->
- handleUpdateModeratorStatus(this, false)
- "click .sidebar-promote-moderator-button": (event) ->
- handleUpdateModeratorStatus(this, true)
-
- initializeUserActiveDiscussion: ($discussion) ->
+ events:
+ "click .sidebar-toggle-moderator-button": "toggleModeratorStatus"
diff --git a/lms/templates/courseware/courseware.html b/lms/templates/courseware/courseware.html
index 141d05352c..2950aa827e 100644
--- a/lms/templates/courseware/courseware.html
+++ b/lms/templates/courseware/courseware.html
@@ -22,6 +22,7 @@
##
<%static:js group='courseware'/>
+ <%static:js group='discussion'/>
<%include file="../discussion/_js_body_dependencies.html" />
diff --git a/lms/templates/discussion/_content_renderer.html b/lms/templates/discussion/_content_renderer.html
index f81fdb612c..54371bf4dd 100644
--- a/lms/templates/discussion/_content_renderer.html
+++ b/lms/templates/discussion/_content_renderer.html
@@ -1,20 +1,20 @@
<%! import django_comment_client.helpers as helpers %>
-<%def name="render_content(content)">
- ${helpers.render_content(content)}
+<%def name="render_content(content, *args, **kwargs)">
+ ${helpers.render_content(content, *args, **kwargs)}
%def>
-<%def name="render_content_with_comments(content)">
+<%def name="render_content_with_comments(content, *args, **kwargs)">