From 07f818da5ae43a8c684dde681ed20b2f132df613 Mon Sep 17 00:00:00 2001 From: Rocky Duan Date: Tue, 21 Aug 2012 02:12:21 -0700 Subject: [PATCH] got reply working under backbone framework --- .../django_comment_client/helpers.py | 7 +- .../django_comment_client/middleware.py | 1 - .../src/backbone_discussion/content.coffee | 139 ++++++++++-------- .../src/backbone_discussion/templates.coffee | 73 --------- .../src/backbone_discussion/utils.coffee | 4 +- .../{ => mustache}/_content.mustache | 0 .../mustache/_edit_comment.mustache | 8 + .../discussion/mustache/_edit_thread.mustache | 10 ++ .../discussion/mustache/_new_post.mustache | 21 +++ .../discussion/mustache/_reply.mustache | 15 ++ 10 files changed, 136 insertions(+), 142 deletions(-) rename lms/templates/discussion/{ => mustache}/_content.mustache (100%) create mode 100644 lms/templates/discussion/mustache/_edit_comment.mustache create mode 100644 lms/templates/discussion/mustache/_edit_thread.mustache create mode 100644 lms/templates/discussion/mustache/_new_post.mustache create mode 100644 lms/templates/discussion/mustache/_reply.mustache diff --git a/lms/djangoapps/django_comment_client/helpers.py b/lms/djangoapps/django_comment_client/helpers.py index b3eff7026d..73bd123e12 100644 --- a/lms/djangoapps/django_comment_client/helpers.py +++ b/lms/djangoapps/django_comment_client/helpers.py @@ -1,5 +1,4 @@ from django.core.urlresolvers import reverse -from django.template.defaultfilters import escapejs from django.conf import settings from mitxmako.shortcuts import render_to_string from mustache_helpers import mustache_helpers @@ -24,11 +23,11 @@ def show_if(text, condition): # TODO there should be a better way to handle this def include_mustache_templates(): - mustache_dir = settings.PROJECT_ROOT / 'templates' / 'discussion' + mustache_dir = settings.PROJECT_ROOT / 'templates' / 'discussion' / 'mustache' valid_file_name = lambda file_name: file_name.endswith('.mustache') read_file = lambda file_name: (file_name, open(mustache_dir / file_name, "r").read()) strip_file_name = lambda x: (x[0].rpartition('.')[0], x[1]) - wrap_in_tag = lambda x: "".format(x[0], escapejs(x[1])) + wrap_in_tag = lambda x: "".format(x[0], x[1]) 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))) @@ -48,4 +47,4 @@ def render_content(content, additional_context={}): context = merge_dict(context, additional_context) partial_mustache_helpers = {k: partial(v, content) for k, v in mustache_helpers.items()} context = merge_dict(context, partial_mustache_helpers) - return render_mustache('discussion/_content.mustache', context) + return render_mustache('discussion/mustache/_content.mustache', context) diff --git a/lms/djangoapps/django_comment_client/middleware.py b/lms/djangoapps/django_comment_client/middleware.py index e79eaf51d4..08e20b0296 100644 --- a/lms/djangoapps/django_comment_client/middleware.py +++ b/lms/djangoapps/django_comment_client/middleware.py @@ -4,7 +4,6 @@ import json class AjaxExceptionMiddleware(object): def process_exception(self, request, exception): - import pdb; pdb.set_trace() if isinstance(exception, CommentClientError) and request.is_ajax(): return JsonError(json.loads(exception.message)) return None diff --git a/lms/static/coffee/src/backbone_discussion/content.coffee b/lms/static/coffee/src/backbone_discussion/content.coffee index 5812c35e87..1b380ecaf4 100644 --- a/lms/static/coffee/src/backbone_discussion/content.coffee +++ b/lms/static/coffee/src/backbone_discussion/content.coffee @@ -18,6 +18,9 @@ class @Content extends Backbone.Model can: (action) -> DiscussionUtil.getContentInfo @id, action + thread_id: -> + if @get('type') == "comment" then @get('thread_id') else @id + initialize: -> @set('comments', new Comments()) if @get('children') @@ -28,99 +31,110 @@ class @ContentView extends Backbone.View $: (selector) -> @$local.find(selector) - showSingleThread: (event) -> - if @showed - @$el.children(".comments").hide() - @showed = false - $showComments = @$(".discussion-show-comments") - prevHtml = $showComments.html() - $showComments.html prevHtml.replace "Hide", "Show" - else - if @retrieved - @$el.children(".comments").show() - @showed = true - else - discussion_id = @model.discussion.id - url = DiscussionUtil.urlFor('retrieve_single_thread', discussion_id, @model.id) - DiscussionUtil.safeAjax - $elem: $.merge @$(".thread-title"), @$(".discussion-show-comments") - url: url - type: "GET" - dataType: 'json' - success: (response, textStatus) => - DiscussionUtil.bulkExtendContentInfo response['annotated_content_info'] - @retrieved = true - @showed = true - @$el.append(response['html']) - @model.get('comments').reset response.content.children, {silent: false} - @initCommentViews() - return - $threadTitle = @$(".thread-title") + discussionContent: -> + @_discussionContent ||= @$el.children(".discussion-content") + + hideSingleThread: (event) -> $showComments = @$(".discussion-show-comments") + @$el.children(".comments").hide() + @showed = false + $showComments.html $showComments.html().replace "Hide", "Show" - if not $showComments.hasClass("first-time") and (not $showComments.length or not $threadTitle.length) - return - - rebindHideEvents = -> - $threadTitle.unbind('click').click @hideSingleThread - $showComments.unbind('click').click @hideSingleThread - $showComments.removeClass("discussion-show-comments") - .addClass("discussion-hide-comments") - prevHtml = $showComments.html() - $showComments.html prevHtml.replace "Show", "Hide" - - if not $showComments.hasClass("first-time") and @$el.children(".comments").length + showSingleThread: (event) -> + $showComments = @$(".discussion-show-comments") + retrieved = not $showComments.hasClass("first-time") and @model.get("children") != undefined + if retrieved @$el.children(".comments").show() - rebindHideEvents() + $showComments.html $showComments.html().replace "Show", "Hide" + @showed = true else discussion_id = @model.discussion.id url = DiscussionUtil.urlFor('retrieve_single_thread', discussion_id, @model.id) DiscussionUtil.safeAjax - $elem: $.merge($threadTitle, $showComments) + $elem: $.merge @$(".thread-title"), @$(".discussion-show-comments") url: url type: "GET" dataType: 'json' success: (response, textStatus) => DiscussionUtil.bulkExtendContentInfo response['annotated_content_info'] + @showed = true + $showComments.html $showComments.html().replace "Show", "Hide" @$el.append(response['html']) + @model.set('children', response.content.children) @model.get('comments').reset response.content.children, {silent: false} @initCommentViews() - $showComments.removeClass("first-time") - rebindHideEvents() + 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 - hideSingleThread: -> - $threadTitle = @$(".thread-title") - $hideComments = @$(".discussion-hide-comments") - $hideComments.removeClass("discussion-hide-comments") - .addClass("discussion-show-comments") - @$el.children(".comments").hide() - $threadTitle.unbind('click').click @showSingleThread - $hideComments.unbind('click').click @showSingleThread - prevHtml = $hideComments.html() - $hideComments.html prevHtml.replace "Hide", "Show" - reply: -> + if @model.get('type') == 'thread' + @showSingleThread() $replyView = @$(".discussion-reply-new") if $replyView.length $replyView.show() else - thread_id = if @model.get('type') == "comment" then @model.get('thread_id') else @model.id + thread_id = @model.thread_id() view = id: @model.id showWatchCheckbox: not DiscussionUtil.isSubscribed(thread_id, "thread") - @$discussionContent.append Mustache.render DiscussionUtil.replyTemplate, view - DiscussionUtil.makeWmdEditor @$el, @$local, "reply-body" - @$(".discussion-submit-post").click @submitReply - @$(".discussion-cancel-post").click @cancelReply + 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) -> + if @model.get('type') == 'thread' + url = DiscussionUtil.urlFor('create_comment', @model.id) + else if @model.get('type') == 'comment' + url = DiscussionUtil.urlFor('create_sub_comment', @model.id) + else + console.error "unrecognized model type #{@model.get('type')}" + return + + 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 + autowatch: 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", "" + #DiscussionUtil.setContentInfo response.content['id'], 'can_reply', true + #DiscussionUtil.setContentInfo response.content['id'], 'editable', true + comment = new Comment(response.content) + DiscussionUtil.extendContentInfo comment.id, response['annotated_content_info'] + @model.get('children').push(response.content) + @model.get('comments').add(comment) + commentView = new CommentView el: $comment[0], model: comment + @$(".discussion-reply-new").hide() + @$(".discussion-reply").show() + @$(".discussion-edit").show() + @discussionContent().attr("status", "normal") cancelReply: -> $replyView = @$(".discussion-reply-new") if $replyView.length @@ -213,7 +227,7 @@ class @ContentView extends Backbone.View body: $local(".thread-raw-body").html() tags: $local(".thread-raw-tags").html() } - $discussionContent.append Mustache.render Discussion.editThreadTemplate, view + @discussionContent().append Mustache.render Discussion.editThreadTemplate, view Discussion.makeWmdEditor $content, $local, "thread-body-edit" $local(".thread-tags-edit").tagsInput Discussion.tagsInputOptions() $local(".discussion-submit-update").unbind("click").click -> handleSubmitEditThread(this) @@ -233,7 +247,7 @@ class @ContentView extends Backbone.View error: Discussion.formErrorHandler($local(".discussion-update-errors")) success: (response, textStatus) -> Discussion.clearFormErrors($local(".discussion-update-errors")) - $discussionContent.replaceWith(response.html) + @discussionContent().replaceWith(response.html) Discussion.extendContentInfo response.content['id'], response['annotated_content_info'] Discussion.initializeContent($content) Discussion.bindContentEvents($content) @@ -262,7 +276,6 @@ class @ContentView extends Backbone.View events: "click .thread-title": "showSingleThread" "click .discussion-show-comments": "showSingleThread" - "click .discussion-hide-comments": "hideSingleThread" "click .discussion-reply-thread": "reply" "click .discussion-reply-comment": "reply" "click .discussion-cancel-reply": "cancelReply" diff --git a/lms/static/coffee/src/backbone_discussion/templates.coffee b/lms/static/coffee/src/backbone_discussion/templates.coffee index 4d43442a16..e69de29bb2 100644 --- a/lms/static/coffee/src/backbone_discussion/templates.coffee +++ b/lms/static/coffee/src/backbone_discussion/templates.coffee @@ -1,73 +0,0 @@ -if not @Discussion? - @Discussion = {} - -Discussion = @Discussion - - -@Discussion = $.extend @Discussion, - - newPostTemplate: """ - - """ - - replyTemplate: """ -
- -
- - - {{#showWatchCheckbox}} - - - {{/showWatchCheckbox}} -
-
- Cancel - Submit -
-
- """ - - editThreadTemplate: """ -
- - -
{{body}}
- -
- Cancel - Update -
-
- """ - - editCommentTemplate: """ -
- -
{{body}}
-
- Cancel - Update -
-
- """ diff --git a/lms/static/coffee/src/backbone_discussion/utils.coffee b/lms/static/coffee/src/backbone_discussion/utils.coffee index 9820a63272..4a49d4e271 100644 --- a/lms/static/coffee/src/backbone_discussion/utils.coffee +++ b/lms/static/coffee/src/backbone_discussion/utils.coffee @@ -143,7 +143,9 @@ class @DiscussionUtil id = $content.attr("_id") appended_id = "-#{cls_identifier}-#{id}" imageUploadUrl = @urlFor('upload') - editor = Markdown.makeWmdEditor elem, appended_id, imageUploadUrl, @postMathJaxProcessor + _processor = (_this) -> + (text) -> _this.postMathJaxProcessor(text) + editor = Markdown.makeWmdEditor elem, appended_id, imageUploadUrl, _processor(@) @wmdEditors["#{cls_identifier}-#{id}"] = editor editor diff --git a/lms/templates/discussion/_content.mustache b/lms/templates/discussion/mustache/_content.mustache similarity index 100% rename from lms/templates/discussion/_content.mustache rename to lms/templates/discussion/mustache/_content.mustache diff --git a/lms/templates/discussion/mustache/_edit_comment.mustache b/lms/templates/discussion/mustache/_edit_comment.mustache new file mode 100644 index 0000000000..72dc7b90a1 --- /dev/null +++ b/lms/templates/discussion/mustache/_edit_comment.mustache @@ -0,0 +1,8 @@ +
+ +
{{body}}
+
+ Cancel + Update +
+
diff --git a/lms/templates/discussion/mustache/_edit_thread.mustache b/lms/templates/discussion/mustache/_edit_thread.mustache new file mode 100644 index 0000000000..a8860ed70d --- /dev/null +++ b/lms/templates/discussion/mustache/_edit_thread.mustache @@ -0,0 +1,10 @@ +
+ + +
{{body}}
+ +
+ Cancel + Update +
+
diff --git a/lms/templates/discussion/mustache/_new_post.mustache b/lms/templates/discussion/mustache/_new_post.mustache new file mode 100644 index 0000000000..451d2e3a93 --- /dev/null +++ b/lms/templates/discussion/mustache/_new_post.mustache @@ -0,0 +1,21 @@ + diff --git a/lms/templates/discussion/mustache/_reply.mustache b/lms/templates/discussion/mustache/_reply.mustache new file mode 100644 index 0000000000..9affe0d8ce --- /dev/null +++ b/lms/templates/discussion/mustache/_reply.mustache @@ -0,0 +1,15 @@ +
+ +
+ + + {{#showWatchCheckbox}} + + + {{/showWatchCheckbox}} +
+
+ Cancel + Submit +
+