diff --git a/lms/djangoapps/django_comment_client/forum/views.py b/lms/djangoapps/django_comment_client/forum/views.py index ae725f2721..8612777dc0 100644 --- a/lms/djangoapps/django_comment_client/forum/views.py +++ b/lms/djangoapps/django_comment_client/forum/views.py @@ -11,7 +11,9 @@ from courseware.courses import check_course from dateutil.tz import tzlocal from datehelper import time_ago_in_words -from django_comment_client.utils import get_categorized_discussion_info, extract, strip_none +from django_comment_client.utils import get_categorized_discussion_info, \ + extract, strip_none, \ + JsonResponse from urllib import urlencode import json @@ -125,24 +127,28 @@ def forum_form_discussion(request, course_id, discussion_id): } return render_to_response('discussion/index.html', context) -def render_single_thread(request, course_id, thread_id): - def get_annotated_content_info(thread, user_id): - infos = {} - def _annotate(content): - infos[str(content['id'])] = { - 'editable': str(content['user_id']) == str(user_id), # TODO may relax this to instructors - } - for child in content['children']: - _annotate(child) - _annotate(thread) - return infos +def get_annotated_content_info(thread, user_id): + infos = {} + def _annotate(content): + infos[str(content['id'])] = { + 'editable': str(content['user_id']) == str(user_id), # TODO may relax this to instructors + } + for child in content['children']: + _annotate(child) + _annotate(thread) + return infos +def render_single_thread(request, course_id, thread_id): + thread = comment_client.get_thread(thread_id, recursive=True) + annotated_content_info = get_annotated_content_info(thread=thread, \ + user_id=request.user.id) + context = { 'thread': thread, 'user_info': comment_client.get_user_info(request.user.id, raw=True), - 'annotated_content_info': json.dumps(get_annotated_content_info(thread=thread, user_id=request.user.id)), + 'annotated_content_info': json.dumps(annotated_content_info), 'course_id': course_id, 'request': request, } @@ -150,17 +156,31 @@ def render_single_thread(request, course_id, thread_id): def single_thread(request, course_id, discussion_id, thread_id): - course = check_course(course_id) + if request.is_ajax(): + + thread = comment_client.get_thread(thread_id, recursive=True) + annotated_content_info = get_annotated_content_info(thread=thread, \ + user_id=request.user.id) + context = {'thread': thread} + html = render_to_string('discussion/_ajax_single_thread.html', context) - context = { - 'csrf': csrf(request)['csrf_token'], - 'init': '', - 'content': render_single_thread(request, course_id, thread_id), - 'accordion': render_accordion(request, course, discussion_id), - 'course': course, - } + return JsonResponse({ + 'html': html, + 'annotated_content_info': annotated_content_info, + }) - return render_to_response('discussion/index.html', context) + else: + course = check_course(course_id) + + context = { + 'csrf': csrf(request)['csrf_token'], + 'init': '', + 'content': render_single_thread(request, course_id, thread_id), + 'accordion': render_accordion(request, course, discussion_id), + 'course': course, + } + + return render_to_response('discussion/index.html', context) def search(request, course_id): diff --git a/lms/static/coffee/src/discussion.coffee b/lms/static/coffee/src/discussion.coffee index cbb31fa3af..8b27e226ba 100644 --- a/lms/static/coffee/src/discussion.coffee +++ b/lms/static/coffee/src/discussion.coffee @@ -11,7 +11,6 @@ $ -> $(".discussion-module").each (index, elem) -> Discussion.initializeDiscussionModule(elem) - $("section.discussion").each (index, discussion) -> Discussion.initializeDiscussion(discussion) @@ -80,28 +79,29 @@ Discussion = """ - urlFor: (name, param) -> + urlFor: (name, param, param1) -> { - watch_commentable : "/courses/#{$$course_id}/discussion/#{param}/watch" - unwatch_commentable : "/courses/#{$$course_id}/discussion/#{param}/unwatch" - create_thread : "/courses/#{$$course_id}/discussion/#{param}/threads/create" - 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" - upvote_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/upvote" - downvote_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/downvote" - watch_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/watch" - unwatch_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/unwatch" - update_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/update" - endorse_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/endorse" - create_sub_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/reply" - delete_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/delete" - upvote_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/upvote" - downvote_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/downvote" - upload : "/courses/#{$$course_id}/discussion/upload" - search : "/courses/#{$$course_id}/discussion/forum/search" - tags_autocomplete : "/courses/#{$$course_id}/discussion/threads/tags/autocomplete" - retrieve_discussion : "/courses/#{$$course_id}/discussion/forum/#{param}/inline" + watch_commentable : "/courses/#{$$course_id}/discussion/#{param}/watch" + unwatch_commentable : "/courses/#{$$course_id}/discussion/#{param}/unwatch" + create_thread : "/courses/#{$$course_id}/discussion/#{param}/threads/create" + 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" + upvote_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/upvote" + downvote_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/downvote" + watch_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/watch" + unwatch_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/unwatch" + update_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/update" + endorse_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/endorse" + create_sub_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/reply" + delete_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/delete" + upvote_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/upvote" + downvote_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/downvote" + upload : "/courses/#{$$course_id}/discussion/upload" + search : "/courses/#{$$course_id}/discussion/forum/search" + tags_autocomplete : "/courses/#{$$course_id}/discussion/threads/tags/autocomplete" + retrieve_discussion : "/courses/#{$$course_id}/discussion/forum/#{param}/inline" + retrieve_single_thread : "/courses/#{$$course_id}/discussion/forum/#{param}/threads/#{param1}" }[name] handleAnchorAndReload: (response) -> @@ -119,7 +119,7 @@ Discussion = $elem.attr("disabled", "disabled") discussion_id = $elem.attr("discussion_id") url = Discussion.urlFor 'retrieve_discussion', discussion_id - $.ajax + $.ajax( url: url method: "GET" success: (data, textStatus, xhr) -> @@ -127,11 +127,13 @@ Discussion = discussion = $local("section.discussion") Discussion.initializeDiscussion(discussion) Discussion.bindDiscussionEvents(discussion) - $elem.removeAttr("disabled") $elem.html("Hide Discussion") $elem.unbind('click').click -> handleHideDiscussion(this) dataType: 'html' + ).always -> + $elem.removeAttr("disabled") + else $local("section.discussion").show() $elem.html("Hide Discussion") @@ -184,8 +186,6 @@ Discussion = watchDiscussion = generateDiscussionLink("discussion-watch-discussion", "Watch", handleWatchDiscussion) $local(".discussion-title-wrapper").append(watchDiscussion) - - initializeWatchThreads = (index, thread) -> $thread = $(thread) id = $thread.attr("_id") @@ -219,16 +219,15 @@ Discussion = $local(".thread").each(initializeVote).each(initializeWatchThreads) initializeWatchDiscussion(discussion) - if $$tags? - $local(".new-post-tags").tagsInput - autocomplete_url: Discussion.urlFor('tags_autocomplete') - autocomplete: - remoteDataType: 'json' - interactive: true - defaultText: "Tag your post" - height: "30px" - width: "90%" - removeWithBackspace: true + $local(".new-post-tags").tagsInput + autocomplete_url: Discussion.urlFor('tags_autocomplete') + autocomplete: + remoteDataType: 'json' + interactive: true + defaultText: "Tag your post" + height: "30px" + width: "90%" + removeWithBackspace: true bindContentEvents: (content) -> @@ -380,7 +379,48 @@ Discussion = # TODO error handling Discussion.handleAnchorAndReload(response) , 'json' + + handleHideSingleThread = (elem) -> + $elem = $(elem) + $content.children(".comments").hide() + $elem.unbind('click').click -> + handleShowSingleThread(this) + + handleShowSingleThread = (elem) -> + $elem = $(elem) + if $elem.attr("disabled") + return + if $content.children(".comments").length + $content.children(".comments").show() + $elem.unbind('click').click -> + handleHideSingleThread(this) + else + $elem.attr("disabled", "disabled") + discussion_id = $elem.parents(".discussion").attr("_id") + url = Discussion.urlFor('retrieve_single_thread', discussion_id, id) + console.log url + $.ajax( + url: url + method: "GET" + success: (response, textStatus) -> + if not $$annotated_content_info? + window.$$annotated_content_info = {} + console.log response + window.$$annotated_content_info = $.extend $$annotated_content_info, response['annotated_content_info'] + console.log $$annotated_content_info + $content.append(response['html']) + $content.find(".comment").each (index, comment) -> + Discussion.initializeContent(comment) + Discussion.bindContentEvents(comment) + $elem.unbind('click').click -> + handleHideSingleThread(this) + dataType: 'json' + ).always -> + $elem.removeAttr("disabled") + + $local(".thread-title").click -> + handleShowSingleThread(this) $local(".discussion-reply").click -> handleReply(this) @@ -402,21 +442,20 @@ Discussion = handleEditThread(this) else handleEditComment(this) - initializeContent: (content) -> $content = $(content) $local = generateLocal($content.children(".discussion-content")) - raw_text = $local(".content-body").html() + $contentBody = $local(".content-body") + raw_text = $contentBody.html() converter = Markdown.getMathCompatibleConverter() - $local(".content-body").html(converter.makeHtml(raw_text)) + $contentBody.html(converter.makeHtml(raw_text)) + MathJax.Hub.Queue ["Typeset", MathJax.Hub, $contentBody.attr("id")] id = $content.attr("_id") if $$annotated_content_info? if not ($$annotated_content_info[id] || [])['editable'] $local(".discussion-edit").remove() - - bindDiscussionEvents: (discussion) -> $discussion = $(discussion) $discussionNonContent = $discussion.children(".discussion-non-content") diff --git a/lms/templates/discussion/_single_thread.html b/lms/templates/discussion/_single_thread.html index dbe3cb181c..9bc37c29c0 100644 --- a/lms/templates/discussion/_single_thread.html +++ b/lms/templates/discussion/_single_thread.html @@ -13,5 +13,8 @@ diff --git a/lms/templates/discussion/_thread.html b/lms/templates/discussion/_thread.html index 220022fc81..3a63684acf 100644 --- a/lms/templates/discussion/_thread.html +++ b/lms/templates/discussion/_thread.html @@ -36,7 +36,7 @@
${render_title(content, type, **kwargs)}
-
${content['body'] | h}
+
${content['body'] | h}
${render_tags(content, type, **kwargs)} ${render_bottom_bar(content, type, **kwargs)} @@ -47,15 +47,8 @@ <%def name="render_title(content, type, **kwargs)"> - <% - if type == "thread": - if kwargs.get('show_comments', False): - url_for_thread = "" - else: - url_for_thread = reverse('django_comment_client.forum.views.single_thread', args=[course_id, content['commentable_id'], content['id']]) - %> % if type == "thread": - ${content['title'] | h} + ${content['title'] | h} % endif