got reply working under backbone framework
This commit is contained in:
@@ -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: "<script type='text/template' id='{0}'>{1}</script>".format(x[0], escapejs(x[1]))
|
||||
wrap_in_tag = lambda x: "<script type='text/template' id='{0}'>{1}</script>".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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
if not @Discussion?
|
||||
@Discussion = {}
|
||||
|
||||
Discussion = @Discussion
|
||||
|
||||
|
||||
@Discussion = $.extend @Discussion,
|
||||
|
||||
newPostTemplate: """
|
||||
<form class="new-post-form collapsed" id="new-post-form" style="display: block; ">
|
||||
<ul class="new-post-form-errors discussion-errors"></ul>
|
||||
<input type="text" class="new-post-title title-input" placeholder="Title" />
|
||||
<div class="new-post-similar-posts-wrapper" style="display: none">
|
||||
Similar Posts:
|
||||
<a class="hide-similar-posts" href="javascript:void(0)">Hide</a>
|
||||
<div class="new-post-similar-posts"></div>
|
||||
</div>
|
||||
<div class="new-post-body reply-body"></div>
|
||||
<input class="new-post-tags" placeholder="Tags" />
|
||||
<div class="post-options">
|
||||
<input type="checkbox" class="discussion-post-anonymously" id="discussion-post-anonymously-${discussion_id}">
|
||||
<label for="discussion-post-anonymously-${discussion_id}">post anonymously</label>
|
||||
<input type="checkbox" class="discussion-auto-watch" id="discussion-autowatch-${discussion_id}" checked="">
|
||||
<label for="discussion-auto-watch-${discussion_id}">follow this thread</label>
|
||||
</div>
|
||||
<div class="new-post-control post-control">
|
||||
<a class="discussion-cancel-post" href="javascript:void(0)">Cancel</a>
|
||||
<a class="discussion-submit-post control-button" href="javascript:void(0)">Submit</a>
|
||||
</div>
|
||||
</form>
|
||||
"""
|
||||
|
||||
replyTemplate: """
|
||||
<form class="discussion-reply-new">
|
||||
<ul class="discussion-errors"></ul>
|
||||
<div class="reply-body"></div>
|
||||
<input type="checkbox" class="discussion-post-anonymously" id="discussion-post-anonymously-{{id}}" />
|
||||
<label for="discussion-post-anonymously-{{id}}">post anonymously</label>
|
||||
{{#showWatchCheckbox}}
|
||||
<input type="checkbox" class="discussion-auto-watch" id="discussion-autowatch-{{id}}" checked />
|
||||
<label for="discussion-auto-watch-{{id}}">follow this thread</label>
|
||||
{{/showWatchCheckbox}}
|
||||
<br />
|
||||
<div class = "reply-post-control">
|
||||
<a class="discussion-cancel-post" href="javascript:void(0)">Cancel</a>
|
||||
<a class="discussion-submit-post control-button" href="javascript:void(0)">Submit</a>
|
||||
</div>
|
||||
</form>
|
||||
"""
|
||||
|
||||
editThreadTemplate: """
|
||||
<form class="discussion-content-edit discussion-thread-edit" _id="{{id}}">
|
||||
<ul class="discussion-errors discussion-update-errors"></ul>
|
||||
<input type="text" class="thread-title-edit title-input" placeholder="Title" value="{{title}}"/>
|
||||
<div class="thread-body-edit body-input">{{body}}</div>
|
||||
<input class="thread-tags-edit" placeholder="Tags" value="{{tags}}" />
|
||||
<div class = "edit-post-control">
|
||||
<a class="discussion-cancel-update" href="javascript:void(0)">Cancel</a>
|
||||
<a class="discussion-submit-update control-button" href="javascript:void(0)">Update</a>
|
||||
</div>
|
||||
</form>
|
||||
"""
|
||||
|
||||
editCommentTemplate: """
|
||||
<form class="discussion-content-edit discussion-comment-edit" _id="{{id}}">
|
||||
<ul class="discussion-errors discussion-update-errors"></ul>
|
||||
<div class="comment-body-edit body-input">{{body}}</div>
|
||||
<div class = "edit-post-control">
|
||||
<a class="discussion-cancel-update" href="javascript:void(0)">Cancel</a>
|
||||
<a class="discussion-submit-update control-button" href="javascript:void(0)">Update</a>
|
||||
</div>
|
||||
</form>
|
||||
"""
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
8
lms/templates/discussion/mustache/_edit_comment.mustache
Normal file
8
lms/templates/discussion/mustache/_edit_comment.mustache
Normal file
@@ -0,0 +1,8 @@
|
||||
<form class="discussion-content-edit discussion-comment-edit" _id="{{id}}">
|
||||
<ul class="discussion-errors discussion-update-errors"></ul>
|
||||
<div class="comment-body-edit body-input">{{body}}</div>
|
||||
<div class = "edit-post-control">
|
||||
<a class="discussion-cancel-update" href="javascript:void(0)">Cancel</a>
|
||||
<a class="discussion-submit-update control-button" href="javascript:void(0)">Update</a>
|
||||
</div>
|
||||
</form>
|
||||
10
lms/templates/discussion/mustache/_edit_thread.mustache
Normal file
10
lms/templates/discussion/mustache/_edit_thread.mustache
Normal file
@@ -0,0 +1,10 @@
|
||||
<form class="discussion-content-edit discussion-thread-edit" _id="{{id}}">
|
||||
<ul class="discussion-errors discussion-update-errors"></ul>
|
||||
<input type="text" class="thread-title-edit title-input" placeholder="Title" value="{{title}}"/>
|
||||
<div class="thread-body-edit body-input">{{body}}</div>
|
||||
<input class="thread-tags-edit" placeholder="Tags" value="{{tags}}" />
|
||||
<div class = "edit-post-control">
|
||||
<a class="discussion-cancel-update" href="javascript:void(0)">Cancel</a>
|
||||
<a class="discussion-submit-update control-button" href="javascript:void(0)">Update</a>
|
||||
</div>
|
||||
</form>
|
||||
21
lms/templates/discussion/mustache/_new_post.mustache
Normal file
21
lms/templates/discussion/mustache/_new_post.mustache
Normal file
@@ -0,0 +1,21 @@
|
||||
<form class="new-post-form collapsed" id="new-post-form" style="display: block; ">
|
||||
<ul class="new-post-form-errors discussion-errors"></ul>
|
||||
<input type="text" class="new-post-title title-input" placeholder="Title" />
|
||||
<div class="new-post-similar-posts-wrapper" style="display: none">
|
||||
Similar Posts:
|
||||
<a class="hide-similar-posts" href="javascript:void(0)">Hide</a>
|
||||
<div class="new-post-similar-posts"></div>
|
||||
</div>
|
||||
<div class="new-post-body reply-body"></div>
|
||||
<input class="new-post-tags" placeholder="Tags" />
|
||||
<div class="post-options">
|
||||
<input type="checkbox" class="discussion-post-anonymously" id="discussion-post-anonymously-${discussion_id}">
|
||||
<label for="discussion-post-anonymously-${discussion_id}">post anonymously</label>
|
||||
<input type="checkbox" class="discussion-auto-watch" id="discussion-autowatch-${discussion_id}" checked="">
|
||||
<label for="discussion-auto-watch-${discussion_id}">follow this thread</label>
|
||||
</div>
|
||||
<div class="new-post-control post-control">
|
||||
<a class="discussion-cancel-post" href="javascript:void(0)">Cancel</a>
|
||||
<a class="discussion-submit-post control-button" href="javascript:void(0)">Submit</a>
|
||||
</div>
|
||||
</form>
|
||||
15
lms/templates/discussion/mustache/_reply.mustache
Normal file
15
lms/templates/discussion/mustache/_reply.mustache
Normal file
@@ -0,0 +1,15 @@
|
||||
<form class="discussion-reply-new">
|
||||
<ul class="discussion-errors"></ul>
|
||||
<div class="reply-body"></div>
|
||||
<input type="checkbox" class="discussion-post-anonymously" id="discussion-post-anonymously-{{id}}" />
|
||||
<label for="discussion-post-anonymously-{{id}}">post anonymously</label>
|
||||
{{#showWatchCheckbox}}
|
||||
<input type="checkbox" class="discussion-auto-watch" id="discussion-autowatch-{{id}}" checked />
|
||||
<label for="discussion-auto-watch-{{id}}">follow this thread</label>
|
||||
{{/showWatchCheckbox}}
|
||||
<br />
|
||||
<div class="reply-post-control">
|
||||
<a class="discussion-cancel-post" href="javascript:void(0)">Cancel</a>
|
||||
<a class="discussion-submit-post control-button" href="javascript:void(0)">Submit</a>
|
||||
</div>
|
||||
</form>
|
||||
Reference in New Issue
Block a user