diff --git a/lms/djangoapps/django_comment_client/forum/views.py b/lms/djangoapps/django_comment_client/forum/views.py index 0abcbf5fbb..925c59a03b 100644 --- a/lms/djangoapps/django_comment_client/forum/views.py +++ b/lms/djangoapps/django_comment_client/forum/views.py @@ -43,6 +43,7 @@ def get_threads(request, course_id, discussion_id=None, per_page=THREADS_PER_PAG 'tags': '', 'commentable_id': discussion_id, 'course_id': course_id, + 'user_id': request.user.id, } if not request.GET.get('sort_key'): @@ -81,6 +82,7 @@ def inline_discussion(request, course_id, discussion_id): # TODO (vshnayder): since none of this code seems to be aware of the fact that # sometimes things go wrong, I suspect that the js client is also not # checking for errors on request. Check and fix as needed. + log.error("Error loading inline discussion threads.") raise Http404 def infogetter(thread): @@ -114,6 +116,7 @@ def forum_form_discussion(request, course_id): unsafethreads, query_params = get_threads(request, course_id) # This might process a search query threads = [utils.safe_content(thread) for thread in unsafethreads] except (cc.utils.CommentClientError, cc.utils.CommentClientUnknownError) as err: + log.error("Error loading forum discussion threads: %s" % str(err)) raise Http404 user_info = cc.User.from_django_user(request.user).to_dict() @@ -164,14 +167,18 @@ def forum_form_discussion(request, course_id): @login_required def single_thread(request, course_id, discussion_id, thread_id): - if request.is_ajax(): - course = get_course_with_access(request.user, course_id, 'load') - user_info = cc.User.from_django_user(request.user).to_dict() + course = get_course_with_access(request.user, course_id, 'load') + cc_user = cc.User.from_django_user(request.user) + user_info = cc_user.to_dict() + + try: + thread = cc.Thread.find(thread_id).retrieve(recursive=True, user_id=request.user.id) + except (cc.utils.CommentClientError, cc.utils.CommentClientUnknownError) as err: + log.error("Error loading single thread.") + raise Http404 + + if request.is_ajax(): - try: - thread = cc.Thread.find(thread_id).retrieve(recursive=True) - except (cc.utils.CommentClientError, cc.utils.CommentClientUnknownError) as err: - raise Http404 courseware_context = get_courseware_context(thread, course) annotated_content_info = utils.get_annotated_content_infos(course_id, thread, request.user, user_info=user_info) @@ -188,13 +195,13 @@ def single_thread(request, course_id, discussion_id, thread_id): }) else: - course = get_course_with_access(request.user, course_id, 'load') category_map = utils.get_discussion_category_map(course) + try: threads, query_params = get_threads(request, course_id) - thread = cc.Thread.find(thread_id).retrieve(recursive=True) threads.append(thread.to_dict()) except (cc.utils.CommentClientError, cc.utils.CommentClientUnknownError) as err: + log.error("Error loading single thread.") raise Http404 course = get_course_with_access(request.user, course_id, 'load') @@ -216,8 +223,7 @@ def single_thread(request, course_id, discussion_id, thread_id): # course_id, #) - user_info = cc.User.from_django_user(request.user).to_dict() - + def infogetter(thread): return utils.get_annotated_content_infos(course_id, thread, request.user, user_info) diff --git a/lms/djangoapps/django_comment_client/utils.py b/lms/djangoapps/django_comment_client/utils.py index 476d5b0a6a..cd323e56c1 100644 --- a/lms/djangoapps/django_comment_client/utils.py +++ b/lms/djangoapps/django_comment_client/utils.py @@ -336,7 +336,8 @@ def safe_content(content): 'endorsed', 'parent_id', 'thread_id', 'votes', 'closed', 'created_at', 'updated_at', 'depth', 'type', 'commentable_id', 'comments_count', 'at_position_list', 'children', 'highlighted_title', 'highlighted_body', - 'courseware_title', 'courseware_url', 'tags' + 'courseware_title', 'courseware_url', 'tags', 'unread_comments_count', + 'read', ] if (content.get('anonymous') is False) and (content.get('anonymous_to_peers') is False): diff --git a/lms/lib/comment_client/thread.py b/lms/lib/comment_client/thread.py index 342711c5fe..424250033e 100644 --- a/lms/lib/comment_client/thread.py +++ b/lms/lib/comment_client/thread.py @@ -60,7 +60,21 @@ class Thread(models.Model): else: return super(Thread, cls).url(action, params) + # TODO: This is currently overriding Model._retrieve only to add parameters + # for the request. Model._retrieve should be modified to handle this such + # that subclasses don't need to override for this. def _retrieve(self, *args, **kwargs): url = self.url(action='get', params=self.attributes) - response = perform_request('get', url, {'recursive': kwargs.get('recursive')}) + + request_params = { + 'recursive': kwargs.get('recursive'), + 'user_id': kwargs.get('user_id'), + 'mark_as_read': kwargs.get('mark_as_read', True), + } + + # user_id may be none, in which case it shouldn't be part of the + # request. + request_params = strip_none(request_params) + + response = perform_request('get', url, request_params) self.update_attributes(**response) diff --git a/lms/static/coffee/src/discussion/discussion_router.coffee b/lms/static/coffee/src/discussion/discussion_router.coffee index a5219a68b9..50c14b20de 100644 --- a/lms/static/coffee/src/discussion/discussion_router.coffee +++ b/lms/static/coffee/src/discussion/discussion_router.coffee @@ -27,6 +27,8 @@ if Backbone? showThread: (forum_name, thread_id) -> @thread = @discussion.get(thread_id) + @thread.set("unread_comments_count", 0) + @thread.set("read", true) @setActiveThread() if(@main) @main.cleanup() diff --git a/lms/static/coffee/src/discussion/views/discussion_thread_list_view.coffee b/lms/static/coffee/src/discussion/views/discussion_thread_list_view.coffee index d998763f50..cca6502158 100644 --- a/lms/static/coffee/src/discussion/views/discussion_thread_list_view.coffee +++ b/lms/static/coffee/src/discussion/views/discussion_thread_list_view.coffee @@ -130,6 +130,8 @@ if Backbone? content.addClass("followed") if thread.get('endorsed') content.addClass("resolved") + if thread.get('read') + content.addClass("read") @highlight(content) diff --git a/lms/static/sass/_discussion.scss b/lms/static/sass/_discussion.scss index 4c8476f301..53b1b5eb9b 100644 --- a/lms/static/sass/_discussion.scss +++ b/lms/static/sass/_discussion.scss @@ -1018,6 +1018,7 @@ body.discussion { text-shadow: 0 -1px 0 rgba(0, 0, 0, .3); box-shadow: 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 1px rgba(0, 0, 0, .2) inset; } + } } @@ -1204,12 +1205,13 @@ body.discussion { background-position: 0 -5px; } - &.new { - @include linear-gradient(top, #84d7fe, #99e0fe); + &.unread { + @include linear-gradient(top, #84d7fe, #60a8d6); color: #333; &:after { color: #99e0fe; + background-position: 0 0px; } } } diff --git a/lms/templates/discussion/_underscore_templates.html b/lms/templates/discussion/_underscore_templates.html index 86e950d42e..fc497a37b2 100644 --- a/lms/templates/discussion/_underscore_templates.html +++ b/lms/templates/discussion/_underscore_templates.html @@ -128,5 +128,13 @@