Commit b913c93f by Arjun Singh

Merge branch 'feature/tomg/new-discussions' of github.com:MITx/mitx into…

Merge branch 'feature/tomg/new-discussions' of github.com:MITx/mitx into feature/tomg/new-discussions
parents f6ee6f2a 70078146
This diff is collapsed. Click to expand it.
...@@ -18,7 +18,7 @@ from django_comment_client.utils import merge_dict, extract, strip_none, strip_b ...@@ -18,7 +18,7 @@ from django_comment_client.utils import merge_dict, extract, strip_none, strip_b
import json import json
import django_comment_client.utils as utils import django_comment_client.utils as utils
import comment_client as cc import comment_client as cc
import xml.sax.saxutils as saxutils
THREADS_PER_PAGE = 50000 THREADS_PER_PAGE = 50000
PAGES_NEARBY_DELTA = 2 PAGES_NEARBY_DELTA = 2
...@@ -143,9 +143,10 @@ def render_search_bar(request, course_id, discussion_id=None, text=''): ...@@ -143,9 +143,10 @@ def render_search_bar(request, course_id, discussion_id=None, text=''):
def forum_form_discussion(request, course_id): def forum_form_discussion(request, course_id):
course = get_course_with_access(request.user, course_id, 'load') course = get_course_with_access(request.user, course_id, 'load')
category_map = utils.get_discussion_category_map(course)
threads, query_params = get_threads(request, course_id) threads, query_params = get_threads(request, course_id)
content = render_forum_discussion(request, course_id, threads, discussion_id=_general_discussion_id(course_id), query_params=query_params) content = render_forum_discussion(request, course_id, threads, discussion_id=_general_discussion_id(course_id), query_params=query_params)
user_info = cc.User.from_django_user(request.user).to_dict()
if request.is_ajax(): if request.is_ajax():
return utils.JsonResponse({ return utils.JsonResponse({
'html': content, 'html': content,
...@@ -161,6 +162,7 @@ def forum_form_discussion(request, course_id): ...@@ -161,6 +162,7 @@ def forum_form_discussion(request, course_id):
trending_tags = cc.search_trending_tags( trending_tags = cc.search_trending_tags(
course_id, course_id,
) )
escapedict = {'"': '"'}
context = { context = {
'csrf': csrf(request)['csrf_token'], 'csrf': csrf(request)['csrf_token'],
'course': course, 'course': course,
...@@ -168,7 +170,10 @@ def forum_form_discussion(request, course_id): ...@@ -168,7 +170,10 @@ def forum_form_discussion(request, course_id):
'recent_active_threads': recent_active_threads, 'recent_active_threads': recent_active_threads,
'trending_tags': trending_tags, 'trending_tags': trending_tags,
'staff_access' : has_access(request.user, course, 'staff'), 'staff_access' : has_access(request.user, course, 'staff'),
'threads': threads, 'threads': saxutils.escape(json.dumps(threads),escapedict),
'user_info': saxutils.escape(json.dumps(user_info),escapedict),
'course_id': course.id,
'category_map': category_map,
} }
# print "start rendering.." # print "start rendering.."
return render_to_response('discussion/index.html', context) return render_to_response('discussion/index.html', context)
...@@ -197,7 +202,7 @@ def render_single_thread(request, discussion_id, course_id, thread_id): ...@@ -197,7 +202,7 @@ def render_single_thread(request, discussion_id, course_id, thread_id):
def single_thread(request, course_id, discussion_id, thread_id): def single_thread(request, course_id, discussion_id, thread_id):
if request.is_ajax(): if request.is_ajax():
user_info = cc.User.from_django_user(request.user).to_dict() user_info = cc.User.from_django_user(request.user).to_dict()
thread = cc.Thread.find(thread_id).retrieve(recursive=True) thread = cc.Thread.find(thread_id).retrieve(recursive=True)
annotated_content_info = utils.get_annotated_content_infos(course_id, thread, request.user, user_info=user_info) annotated_content_info = utils.get_annotated_content_infos(course_id, thread, request.user, user_info=user_info)
...@@ -226,19 +231,19 @@ def single_thread(request, course_id, discussion_id, thread_id): ...@@ -226,19 +231,19 @@ def single_thread(request, course_id, discussion_id, thread_id):
) )
user_info = cc.User.from_django_user(request.user).to_dict() user_info = cc.User.from_django_user(request.user).to_dict()
escapedict = {'"': '"'}
context = { context = {
'discussion_id': discussion_id, 'discussion_id': discussion_id,
'csrf': csrf(request)['csrf_token'], 'csrf': csrf(request)['csrf_token'],
'init': '', 'init': '',
'user_info': json.dumps(user_info), 'user_info': saxutils.escape(json.dumps(user_info),escapedict),
'content': render_single_thread(request, discussion_id, course_id, thread_id), 'content': render_single_thread(request, discussion_id, course_id, thread_id),
'course': course, 'course': course,
'recent_active_threads': recent_active_threads, 'recent_active_threads': recent_active_threads,
'trending_tags': trending_tags, 'trending_tags': trending_tags,
'course_id': course.id, 'course_id': course.id,
'thread_id': thread_id, 'thread_id': thread_id,
'threads': json.dumps(threads), 'threads': saxutils.escape(json.dumps(threads), escapedict),
'category_map': category_map, 'category_map': category_map,
} }
......
...@@ -8,6 +8,7 @@ class User(models.Model): ...@@ -8,6 +8,7 @@ class User(models.Model):
accessible_fields = ['username', 'email', 'follower_ids', 'upvoted_ids', 'downvoted_ids', accessible_fields = ['username', 'email', 'follower_ids', 'upvoted_ids', 'downvoted_ids',
'id', 'external_id', 'subscribed_user_ids', 'children', 'course_id', 'id', 'external_id', 'subscribed_user_ids', 'children', 'course_id',
'subscribed_thread_ids', 'subscribed_commentable_ids', 'subscribed_thread_ids', 'subscribed_commentable_ids',
'default_sort_key',
'threads_count', 'comments_count', 'threads_count', 'comments_count',
] ]
......
...@@ -47,6 +47,7 @@ if Backbone? ...@@ -47,6 +47,7 @@ if Backbone?
initialize: -> initialize: ->
DiscussionUtil.addContent @id, @ DiscussionUtil.addContent @id, @
@set 'user_url', DiscussionUtil.urlFor('user_profile', @get('user_id'))
@resetComments(@get('children')) @resetComments(@get('children'))
......
...@@ -3,7 +3,6 @@ if Backbone? ...@@ -3,7 +3,6 @@ if Backbone?
model: Thread model: Thread
initialize: -> initialize: ->
DiscussionUtil.addDiscussion @id, @
@bind "add", (item) => @bind "add", (item) =>
item.discussion = @ item.discussion = @
@comparator = @sortByDate @comparator = @sortByDate
......
...@@ -13,7 +13,8 @@ class @DiscussionRouter extends Backbone.Router ...@@ -13,7 +13,8 @@ class @DiscussionRouter extends Backbone.Router
@newPostView = new NewPostView(el: $(".new-post-article")) @newPostView = new NewPostView(el: $(".new-post-article"))
allThreads: -> allThreads: ->
true # TODO: Do something reasonable here
$(".discussion-column").html("No thread selected.")
setActiveThread: => setActiveThread: =>
if @thread if @thread
......
DiscussionApp =
start: (elem)->
# TODO: Perhaps eliminate usage of global variables when possible
element = $(elem)
window.$$contents = {}
window.$$course_id = element.data("course-id")
user_info = element.data("user-info")
threads = element.data("threads")
window.user = new DiscussionUser(user_info)
discussion = new Discussion(threads)
new DiscussionRouter({discussion: discussion})
Backbone.history.start({pushState: true, root: "/courses/#{$$course_id}/discussion/forum/"})
$ ->
$("section.discussion").each (index, elem) ->
DiscussionApp.start(elem)
...@@ -13,16 +13,9 @@ class @DiscussionUtil ...@@ -13,16 +13,9 @@ class @DiscussionUtil
@getTemplate: (id) -> @getTemplate: (id) ->
$("script##{id}").html() $("script##{id}").html()
@getDiscussionData: (id) ->
return $$discussion_data[id]
@addContent: (id, content) -> window.$$contents[id] = content @addContent: (id, content) -> window.$$contents[id] = content
@getContent: (id) -> window.$$contents[id] @getContent: (id) -> window.$$contents[id]
@addDiscussion: (id, discussion) -> window.$$discussions[id] = discussion
@getDiscussion: (id) -> window.$$discussions[id]
@bulkUpdateContentInfo: (infos) -> @bulkUpdateContentInfo: (infos) ->
for id, info of infos for id, info of infos
...@@ -64,21 +57,25 @@ class @DiscussionUtil ...@@ -64,21 +57,25 @@ class @DiscussionUtil
openclose_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/close" openclose_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/close"
permanent_link_thread : "/courses/#{$$course_id}/discussion/forum/#{param}/threads/#{param1}" permanent_link_thread : "/courses/#{$$course_id}/discussion/forum/#{param}/threads/#{param1}"
permanent_link_comment : "/courses/#{$$course_id}/discussion/forum/#{param}/threads/#{param1}##{param2}" permanent_link_comment : "/courses/#{$$course_id}/discussion/forum/#{param}/threads/#{param1}##{param2}"
user_profile : "/courses/#{$$course_id}/discussion/forum/users/#{param}"
}[name] }[name]
@safeAjax: (params) -> @safeAjax: (params) ->
$elem = params.$elem $elem = params.$elem
if $elem.attr("disabled") if $elem and $elem.attr("disabled")
return return
params["url"] = URI(params["url"]).addSearch ajax: 1
params["beforeSend"] = -> params["beforeSend"] = ->
$elem.attr("disabled", "disabled") if $elem
$elem.attr("disabled", "disabled")
if params["$loading"] if params["$loading"]
if params["loadingCallback"]? if params["loadingCallback"]?
params["loadingCallback"].apply(params["$loading"]) params["loadingCallback"].apply(params["$loading"])
else else
params["$loading"].loading() params["$loading"].loading()
$.ajax(params).always -> $.ajax(params).always ->
$elem.removeAttr("disabled") if $elem
$elem.removeAttr("disabled")
if params["$loading"] if params["$loading"]
if params["loadedCallback"]? if params["loadedCallback"]?
params["loadedCallback"].apply(params["$loading"]) params["loadedCallback"].apply(params["$loading"])
......
...@@ -29,10 +29,12 @@ class @DiscussionThreadView extends Backbone.View ...@@ -29,10 +29,12 @@ class @DiscussionThreadView extends Backbone.View
MathJax.Hub.Queue ["Typeset", MathJax.Hub, element.attr("id")] MathJax.Hub.Queue ["Typeset", MathJax.Hub, element.attr("id")]
renderResponses: -> renderResponses: ->
$.ajax @model.id, success: (data, textStatus, xhr) => DiscussionUtil.safeAjax
@$(".loading").remove() url: @model.id
comments = new Comments(data['content']['children']) success: (data, textStatus, xhr) =>
comments.each @renderResponse @$(".loading").remove()
comments = new Comments(data['content']['children'])
comments.each @renderResponse
renderResponse: (response) => renderResponse: (response) =>
view = new ThreadResponseView(model: response) view = new ThreadResponseView(model: response)
......
...@@ -57,12 +57,15 @@ class @ThreadResponseView extends Backbone.View ...@@ -57,12 +57,15 @@ class @ThreadResponseView extends Backbone.View
if textStatus == 'success' if textStatus == 'success'
@model.set(response) @model.set(response)
submitComment: -> submitComment: (event) ->
url = @model.urlFor('reply') url = @model.urlFor('reply')
body = @$(".comment-form-input").val() body = @$(".comment-form-input").val()
if not body.trim().length
return false
comment = new Comment(body: body, created_at: (new Date()).toISOString(), username: window.user.get("username")) comment = new Comment(body: body, created_at: (new Date()).toISOString(), username: window.user.get("username"))
@renderComment(comment) @renderComment(comment)
@trigger "comment:add" @trigger "comment:add"
@$(".comment-form-input").val("")
DiscussionUtil.safeAjax DiscussionUtil.safeAjax
$elem: $(event.target) $elem: $(event.target)
...@@ -71,4 +74,5 @@ class @ThreadResponseView extends Backbone.View ...@@ -71,4 +74,5 @@ class @ThreadResponseView extends Backbone.View
dataType: 'json' dataType: 'json'
data: data:
body: body body: body
false false
...@@ -844,6 +844,7 @@ body.discussion { ...@@ -844,6 +844,7 @@ body.discussion {
background: #fff; background: #fff;
box-shadow: 0 1px 2px rgba(0, 0, 0, .05); box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
width: 68%; width: 68%;
min-height: 500px
} }
.discussion-article { .discussion-article {
......
<%namespace name="renderer" file="_content_renderer.html"/> <%namespace name="renderer" file="_content_renderer.html"/>
<%! from django_comment_client.mustache_helpers import url_for_user %>
<article class="discussion-article" data-id="${discussion_id| h}"> <article class="discussion-article" data-id="${discussion_id| h}">
<a href="#" class="dogear"></a> <a href="#" class="dogear"></a>
...@@ -8,7 +9,7 @@ ...@@ -8,7 +9,7 @@
<h1>${thread['title']}</h1> <h1>${thread['title']}</h1>
<p class="posted-details"> <p class="posted-details">
<span class="timeago" title="${thread['created_at'] | h}">sometime</span> by <span class="timeago" title="${thread['created_at'] | h}">sometime</span> by
<a href="${thread['user_id']}">${thread['username']}</a> <a href="${url_for_user(thread, thread['user_id'])}">${thread['username']}</a>
</p> </p>
</header> </header>
<div class="post-body"> <div class="post-body">
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
<h1>${'<%= title %>'}</h1> <h1>${'<%= title %>'}</h1>
<p class="posted-details"> <p class="posted-details">
<span class="timeago" title="${'<%= created_at %>'}">sometime</span> by <span class="timeago" title="${'<%= created_at %>'}">sometime</span> by
<a href="${'<%= user_id %>'}">${'<%= username %>'}</a> <a href="${'<%= user_url %>'}">${'<%= username %>'}</a>
</p> </p>
</header> </header>
<div class="post-body"> <div class="post-body">
...@@ -58,7 +58,7 @@ ...@@ -58,7 +58,7 @@
<script type="text/template" id="thread-response-template"> <script type="text/template" id="thread-response-template">
<header> <header>
<a href="#" class="vote-btn" data-tooltip="vote"><span class="plus-icon"></span><span class="votes-count-number">${"<%= votes['up_count'] %>"}</span></a> <a href="#" class="vote-btn" data-tooltip="vote"><span class="plus-icon"></span><span class="votes-count-number">${"<%= votes['up_count'] %>"}</span></a>
<a href="#" class="posted-by">${"<%= username %>"}</a> <a href="${'<%= user_url %>'}" class="posted-by">${"<%= username %>"}</a>
<p class="posted-details" title="${'<%= created_at %>'}">Sometime</p> <p class="posted-details" title="${'<%= created_at %>'}">Sometime</p>
</header> </header>
<div class="response-body">${"<%= body %>"}</div> <div class="response-body">${"<%= body %>"}</div>
...@@ -72,7 +72,7 @@ ...@@ -72,7 +72,7 @@
</script> </script>
<script type="text/template" id="response-comment-template"> <script type="text/template" id="response-comment-template">
<p>${'<%= body %>'}<span class="posted-details">posted <span class="timeago" title="${'<%= created_at %>'}">sometime</span> by <a href="#">${'<%= username %>'}</a></span></p> <p>${'<%= body %>'}<span class="posted-details">posted <span class="timeago" title="${'<%= created_at %>'}">sometime</span> by <a href="${'<%= user_url %>'}">${'<%= username %>'}</a></span></p>
</script> </script>
<script type="text/template" id="thread-list-item-template"> <script type="text/template" id="thread-list-item-template">
......
<%! import django_comment_client.helpers as helpers %> <%! import django_comment_client.helpers as helpers %>
<%! from django.template.defaultfilters import escapejs %>
<%! from django.core.urlresolvers import reverse %>
<%inherit file="../main.html" /> <%inherit file="../main.html" />
<%namespace name='static' file='../static_content.html'/> <%namespace name='static' file='../static_content.html'/>
<%block name="bodyclass">discussion</%block> <%block name="bodyclass">discussion</%block>
...@@ -16,51 +19,15 @@ ...@@ -16,51 +19,15 @@
<%include file="../courseware/course_navigation.html" args="active_page='discussion'" /> <%include file="../courseware/course_navigation.html" args="active_page='discussion'" />
<%include file="_new_post.html" />
<section class="container"> <script type="text/javascript" src="${static.url('js/discussions-temp.js')}"></script>
<div class="discussion-wrapper">
<article class="discussion-sidebar">
<div class="board-selector">
<a href="#" class="board-drop-btn">Homework / Week 1 <span class="drop-arrow"></span></a>
<div class="board-drop-menu">
</div>
</div>
<div class="sort-bar">
<a href="#"><span class="sort-label">Sort by:</span> most recent <span class="drop-arrow"></span></a>
</div>
<div class="post-list-wrapper">
<ul class="post-list">
% for thread in threads:
<li><a href="${helpers.permalink(thread) | h}"><span class="title">${thread['title'] | h}</span> <span class="comments">${thread['comments_count'] | h}</span><span class="votes">+${thread['votes']['up_count'] | h}</span></a></li>
% endfor
</ul>
</div>
</article>
<section class="discussion-content">
This page intentionally left blank
</section>
</div>
<section class="discussion container" id="discussion-container" data-course-id="${course_id}" data-user-info="${user_info}" data-threads="${threads}">
<div class="discussion-body">
<div class="sidebar"></div>
<div class="discussion-column"></div>
</div>
</section> </section>
<section class="container"> <%include file="_underscore_templates.html" />
<div class="course-wrapper"> \ No newline at end of file
<section aria-label="Course Navigation" class="course-index">
<nav>
<article class="sidebar-module discussion-sidebar">
<a href="#" class="sidebar-new-post-button">New Post</a>
</article>
<%include file="_recent_active_posts.html" />
<%include file="_trending_tags.html" />
</nav>
</section>
<section class="course-content">
${content.decode('utf-8')}
</section>
</div>
</section>
...@@ -17,23 +17,7 @@ ...@@ -17,23 +17,7 @@
<%include file="_js_body_dependencies.html" /> <%include file="_js_body_dependencies.html" />
<%static:js group='discussion'/> <%static:js group='discussion'/>
<script type="text/javascript" src="${static.url('js/discussions-temp.js')}"></script> <script type="text/javascript" src="${static.url('js/discussions-temp.js')}"></script>
<script>
$$contents = {};
$$discussions = {};
$$course_id = "${course_id}";
DiscussionApp = {
start: function() {
window.user = new DiscussionUser(JSON.parse("${user_info | escapejs}"));
var discussion = new Discussion(JSON.parse("${threads | escapejs}"));
new DiscussionRouter({discussion: discussion});
Backbone.history.start({pushState: true, root: "/courses/${course_id}/discussion/forum/"});
}
}
$(document).ready(function() {
DiscussionApp.start();
});
</script>
</%block> </%block>
<nav class="course-material"> <nav class="course-material">
...@@ -71,11 +55,11 @@ ...@@ -71,11 +55,11 @@
<%include file="_new_post.html" /> <%include file="_new_post.html" />
<div class="discussion container"> <section class="discussion container" id="discussion-container" data-course-id="${course_id}" data-user-info="${user_info}" data-threads="${threads}">
<div class="discussion-body"> <div class="discussion-body">
<div class="sidebar"></div> <div class="sidebar"></div>
<div class="discussion-column"></div> <div class="discussion-column"></div>
</div> </div>
</div> </section>
<%include file="_underscore_templates.html" /> <%include file="_underscore_templates.html" />
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment