From c655c5a678fd202e10cf986e53e9e40fd5d67a79 Mon Sep 17 00:00:00 2001 From: Brian Jacobel Date: Fri, 4 Nov 2016 15:41:23 -0400 Subject: [PATCH] Add new DiscussionInlineView which uses DiscussionThreadListView --- .../xmodule/js/src/discussion/display.coffee | 2 +- .../js/discussion/discussion_module_view.js | 265 ------------------ .../views/discussion_inline_view.js | 163 +++++++++++ .../discussion/inline-discussion.underscore | 7 - .../static/teams/js/views/team_discussion.js | 13 +- lms/static/lms/js/build.js | 2 +- lms/static/lms/js/spec/main.js | 4 +- lms/static/sass/discussion/_discussion.scss | 9 +- .../sass/discussion/elements/_navigation.scss | 6 + .../discussion/_discussion_inline.html | 6 +- .../discussion/_js_body_dependencies.html | 2 +- .../discussion/_thread_list_template.html | 5 +- 12 files changed, 191 insertions(+), 293 deletions(-) delete mode 100644 common/static/common/js/discussion/discussion_module_view.js create mode 100644 common/static/common/js/discussion/views/discussion_inline_view.js diff --git a/common/lib/xmodule/xmodule/js/src/discussion/display.coffee b/common/lib/xmodule/xmodule/js/src/discussion/display.coffee index a350cf9866..2369b0f92d 100644 --- a/common/lib/xmodule/xmodule/js/src/discussion/display.coffee +++ b/common/lib/xmodule/xmodule/js/src/discussion/display.coffee @@ -1,4 +1,4 @@ class @InlineDiscussion extends XModule.Descriptor constructor: (element) -> @el = $(element).find('.discussion-module') - @view = new DiscussionModuleView(el: @el) + @view = new DiscussionInlineView(el: @el) diff --git a/common/static/common/js/discussion/discussion_module_view.js b/common/static/common/js/discussion/discussion_module_view.js deleted file mode 100644 index 36ed2a4859..0000000000 --- a/common/static/common/js/discussion/discussion_module_view.js +++ /dev/null @@ -1,265 +0,0 @@ -/* globals Discussion, DiscussionUtil, DiscussionUser, DiscussionCourseSettings, DiscussionThreadView, Content, -NewPostView */ -(function() { - 'use strict'; - var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { - for (var key in parent) { - if (__hasProp.call(parent, key)) { - child[key] = parent[key]; - } - } - function ctor() { - this.constructor = child; - } - - ctor.prototype = parent.prototype; - child.prototype = new ctor(); - child.__super__ = parent.prototype; - return child; - }; - - if (typeof Backbone !== 'undefined' && Backbone !== null) { - this.DiscussionModuleView = (function(_super) { - __extends(DiscussionModuleView, _super); - - function DiscussionModuleView() { - var self = this; - this.navigateToPage = function() { - return DiscussionModuleView.prototype.navigateToPage.apply(self, arguments); - }; - this.renderPagination = function() { - return DiscussionModuleView.prototype.renderPagination.apply(self, arguments); - }; - this.addThread = function() { - return DiscussionModuleView.prototype.addThread.apply(self, arguments); - }; - this.renderDiscussion = function() { - return DiscussionModuleView.prototype.renderDiscussion.apply(self, arguments); - }; - this.loadPage = function() { - return DiscussionModuleView.prototype.loadPage.apply(self, arguments); - }; - this.toggleDiscussion = function() { - return DiscussionModuleView.prototype.toggleDiscussion.apply(self, arguments); - }; - this.hideDiscussion = function() { - return DiscussionModuleView.prototype.hideDiscussion.apply(self, arguments); - }; - this.hideNewPost = function() { - return DiscussionModuleView.prototype.hideNewPost.apply(self, arguments); - }; - this.toggleNewPost = function() { - return DiscussionModuleView.prototype.toggleNewPost.apply(self, arguments); - }; - return DiscussionModuleView.__super__.constructor.apply(this, arguments); - } - - DiscussionModuleView.prototype.events = { - 'click .discussion-show': 'toggleDiscussion', - 'keydown .discussion-show': function(event) { - return DiscussionUtil.activateOnSpace(event, this.toggleDiscussion); - }, - 'click .new-post-btn': 'toggleNewPost', - 'keydown .new-post-btn': function(event) { - return DiscussionUtil.activateOnSpace(event, this.toggleNewPost); - }, - 'click .discussion-paginator a': 'navigateToPage' - }; - - DiscussionModuleView.prototype.page_re = /\?discussion_page=(\d+)/; - - DiscussionModuleView.prototype.initialize = function(options) { - var match; - this.toggleDiscussionBtn = this.$('.discussion-show'); - match = this.page_re.exec(window.location.href); - this.context = options.context || 'course'; - this.readOnly = $('.discussion-module').data('read-only'); - if (match) { - this.page = parseInt(match[1]); - } else { - this.page = 1; - } - }; - - DiscussionModuleView.prototype.toggleNewPost = function(event) { - event.preventDefault(); - if (!this.newPostForm) { - this.toggleDiscussion(); - this.isWaitingOnNewPost = true; - return; - } - if (this.showed) { - this.newPostForm.slideDown(300); - } else { - this.newPostForm.show().focus(); - } - this.toggleDiscussionBtn.addClass('shown'); - this.toggleDiscussionBtn.find('.button-text').html(gettext('Hide Discussion')); - this.$('section.discussion').slideDown(); - this.showed = true; - }; - - DiscussionModuleView.prototype.hideNewPost = function() { - return this.newPostForm.slideUp(300); - }; - - DiscussionModuleView.prototype.hideDiscussion = function() { - this.$('section.discussion').slideUp(); - this.toggleDiscussionBtn.removeClass('shown'); - this.toggleDiscussionBtn.find('.button-text').html(gettext('Show Discussion')); - this.showed = false; - }; - - DiscussionModuleView.prototype.toggleDiscussion = function() { - var $elem, - self = this; - if (this.showed) { - return this.hideDiscussion(); - } else { - this.toggleDiscussionBtn.addClass('shown'); - this.toggleDiscussionBtn.find('.button-text').html(gettext('Hide Discussion')); - if (this.retrieved) { - this.$('section.discussion').slideDown(); - this.showed = true; - } else { - $elem = this.toggleDiscussionBtn; - return this.loadPage($elem, function() { - self.hideDiscussion(); - return DiscussionUtil.discussionAlert( - gettext('Sorry'), - gettext('We had some trouble loading the discussion. Please try again.') - ); - }); - } - } - }; - - DiscussionModuleView.prototype.loadPage = function($elem, error) { - var discussionId, url, - self = this; - discussionId = this.$el.data('discussion-id'); - url = DiscussionUtil.urlFor('retrieve_discussion', discussionId) + ('?page=' + this.page); - return DiscussionUtil.safeAjax({ - $elem: $elem, - $loading: $elem, - takeFocus: true, - url: url, - type: 'GET', - dataType: 'json', - success: function(response, textStatus) { - return self.renderDiscussion($elem, response, textStatus, discussionId); - }, - error: error - }); - }; - - DiscussionModuleView.prototype.renderDiscussion = function($elem, response, textStatus, discussionId) { - var $discussion, user, - self = this; - $elem.focus(); - user = new DiscussionUser(response.user_info); - window.user = user; - DiscussionUtil.setUser(user); - Content.loadContentInfos(response.annotated_content_info); - DiscussionUtil.loadRoles(response.roles); - this.course_settings = new DiscussionCourseSettings(response.course_settings); - this.discussion = new Discussion(); - this.discussion.reset(response.discussion_data, { - silent: false - }); - $discussion = _.template($('#inline-discussion-template').html())({ - 'threads': response.discussion_data, - read_only: this.readOnly, - 'discussionId': discussionId - }); - if (this.$('section.discussion').length) { - this.$('section.discussion').replaceWith($discussion); - } else { - this.$el.append($discussion); - } - this.newPostForm = this.$el.find('.new-post-article'); - this.threadviews = this.discussion.map(function(thread) { - var view; - view = new DiscussionThreadView({ - el: self.$('article#thread_' + thread.id), - model: thread, - mode: 'inline', - context: self.context, - course_settings: self.course_settings, - topicId: discussionId - }); - thread.on('thread:thread_type_updated', function() { - view.rerender(); - return view.expand(); - }); - return view; - }); - _.each(this.threadviews, function(dtv) { - return dtv.render(); - }); - DiscussionUtil.bulkUpdateContentInfo(window.$$annotated_content_info); - this.newPostView = new NewPostView({ - el: this.newPostForm, - collection: this.discussion, - course_settings: this.course_settings, - topicId: discussionId, - is_commentable_cohorted: response.is_commentable_cohorted - }); - this.newPostView.render(); - this.listenTo(this.newPostView, 'newPost:cancel', this.hideNewPost); - this.discussion.on('add', this.addThread); - this.retrieved = true; - this.showed = true; - this.renderPagination(response.num_pages); - if (this.isWaitingOnNewPost) { - return this.newPostForm.show().focus(); - } - }; - - DiscussionModuleView.prototype.addThread = function(thread) { - var article, threadView; - article = $("
"); - this.$('section.discussion > .threads').prepend(article); - threadView = new DiscussionThreadView({ - el: article, - model: thread, - mode: 'inline', - context: this.context, - course_settings: this.course_settings, - topicId: this.$el.data('discussion-id') - }); - threadView.render(); - return this.threadviews.unshift(threadView); - }; - - DiscussionModuleView.prototype.renderPagination = function(numPages) { - var pageUrl, pagination, params; - pageUrl = function(number) { - return '?discussion_page=' + number; - }; - params = DiscussionUtil.getPaginationParams(this.page, numPages, pageUrl); - pagination = _.template($('#pagination-template').html())(params); - return this.$('section.discussion-pagination').html(pagination); - }; - - DiscussionModuleView.prototype.navigateToPage = function(event) { - var currPage, - self = this; - event.preventDefault(); - window.history.pushState({}, window.document.title, event.target.href); - currPage = this.page; - this.page = $(event.target).data('page-number'); - return this.loadPage($(event.target), function() { - self.page = currPage; - DiscussionUtil.discussionAlert( - gettext('Sorry'), - gettext('We had some trouble loading the threads you requested. Please try again.') - ); - }); - }; - - return DiscussionModuleView; - })(Backbone.View); - } -}).call(window); diff --git a/common/static/common/js/discussion/views/discussion_inline_view.js b/common/static/common/js/discussion/views/discussion_inline_view.js new file mode 100644 index 0000000000..f897edfac2 --- /dev/null +++ b/common/static/common/js/discussion/views/discussion_inline_view.js @@ -0,0 +1,163 @@ +/* globals + _, Backbone, Content, Discussion, DiscussionUtil, DiscussionUser, DiscussionCourseSettings, + DiscussionThreadListView, NewPostView +*/ + +(function() { + 'use strict'; + + this.DiscussionInlineView = Backbone.View.extend({ + events: { + 'click .discussion-show': 'toggleDiscussion', + 'keydown .discussion-show': function(event) { + return DiscussionUtil.activateOnSpace(event, this.toggleDiscussion); + }, + 'click .new-post-btn': 'toggleNewPost', + 'keydown .new-post-btn': function(event) { + return DiscussionUtil.activateOnSpace(event, this.toggleNewPost); + } + }, + + initialize: function(options) { + this.$el = options.el; + this.toggleDiscussionBtn = this.$('.discussion-show'); + this.newPostForm = this.$el.find('.new-post-article'); + this.listenTo(this.newPostView, 'newPost:cancel', this.hideNewPost); + }, + + loadDiscussions: function($elem, error) { + var discussionId = this.$el.data('discussion-id'), + url = DiscussionUtil.urlFor('retrieve_discussion', discussionId) + ('?page=' + this.page), + self = this; + + DiscussionUtil.safeAjax({ + $elem: this.$el, + $loading: this.$el, + takeFocus: true, + url: url, + type: 'GET', + dataType: 'json', + success: function(response, textStatus) { + self.renderDiscussion(self.$el, response, textStatus, discussionId); + }, + error: error + }); + }, + + renderDiscussion: function($elem, response, textStatus, discussionId) { + var $discussion, + user = new DiscussionUser(response.user_info), + self = this; + + $elem.focus(); + + window.user = user; + DiscussionUtil.setUser(user); + Content.loadContentInfos(response.annotated_content_info); + DiscussionUtil.loadRoles(response.roles); + + this.course_settings = new DiscussionCourseSettings(response.course_settings); + + this.discussion = new Discussion(); + this.discussion.reset(response.discussion_data, { + silent: false + }); + + $discussion = _.template($('#inline-discussion-template').html())({ + threads: response.discussion_data, + read_only: this.readOnly, + discussionId: discussionId + }); + + if (this.$('section.discussion').length) { + this.$('section.discussion').replaceWith($discussion); + } else { + this.$el.append($discussion); + } + + this.threadListView = new DiscussionThreadListView({ + el: this.$('section.threads'), + collection: self.discussion, + courseSettings: self.course_settings + }); + + this.threadListView.render(); + + DiscussionUtil.bulkUpdateContentInfo(window.$$annotated_content_info); + + this.newPostForm = this.$el.find('.new-post-article'); + + this.newPostView = new NewPostView({ + el: this.newPostForm, + collection: this.discussion, + course_settings: this.course_settings, + topicId: discussionId, + is_commentable_cohorted: response.is_commentable_cohorted + }); + + this.newPostView.render(); + + this.listenTo(this.newPostView, 'newPost:cancel', this.hideNewPost); + this.discussion.on('add', this.addThread); + + this.retrieved = true; + this.showed = true; + + if (this.isWaitingOnNewPost) { + this.newPostForm.show().focus(); + } + }, + + toggleDiscussion: function() { + var self = this; + + if (this.showed) { + this.hideDiscussion(); + } else { + this.toggleDiscussionBtn.addClass('shown'); + this.toggleDiscussionBtn.find('.button-text').html(gettext('Hide Discussion')); + if (this.retrieved) { + this.$('section.discussion').slideDown(); + this.showed = true; + } else { + this.loadDiscussions(this.$el, function() { + self.hideDiscussion(); + DiscussionUtil.discussionAlert( + gettext('Sorry'), + gettext('We had some trouble loading the discussion. Please try again.') + ); + }); + } + } + }, + + hideDiscussion: function() { + this.$('section.discussion').slideUp(); + this.toggleDiscussionBtn.removeClass('shown'); + this.toggleDiscussionBtn.find('.button-text').html(gettext('Show Discussion')); + this.showed = false; + }, + + toggleNewPost: function(event) { + event.preventDefault(); + if (!this.newPostForm) { + this.toggleDiscussion(); + this.isWaitingOnNewPost = true; + return; + } + if (this.showed) { + this.newPostForm.slideDown(300); + } else { + this.newPostForm.show().focus(); + } + this.toggleDiscussionBtn.addClass('shown'); + this.toggleDiscussionBtn.find('.button-text').html(gettext('Hide Discussion')); + this.$('section.discussion').slideDown(); + this.showed = true; + }, + + hideNewPost: function() { + return this.newPostForm.slideUp(300); + } + }); +}).call(window); diff --git a/common/static/common/templates/discussion/inline-discussion.underscore b/common/static/common/templates/discussion/inline-discussion.underscore index 908c2d2380..45dae2d95d 100644 --- a/common/static/common/templates/discussion/inline-discussion.underscore +++ b/common/static/common/templates/discussion/inline-discussion.underscore @@ -6,12 +6,5 @@
- <% _.each(threads, function(thread) { %> -
-
- <% }); %> -
- -
diff --git a/lms/djangoapps/teams/static/teams/js/views/team_discussion.js b/lms/djangoapps/teams/static/teams/js/views/team_discussion.js index 2d4d336523..dd3dac878b 100644 --- a/lms/djangoapps/teams/static/teams/js/views/team_discussion.js +++ b/lms/djangoapps/teams/static/teams/js/views/team_discussion.js @@ -3,21 +3,18 @@ */ (function(define) { 'use strict'; - define(['backbone', 'underscore', 'gettext', 'common/js/discussion/discussion_module_view'], - function(Backbone, _, gettext, DiscussionModuleView) { + define(['backbone', 'underscore', 'gettext', 'common/js/discussion/views/discussion_inline_view'], + function(Backbone, _, gettext, DiscussionInlineView) { var TeamDiscussionView = Backbone.View.extend({ initialize: function() { window.$$course_id = this.$el.data('course-id'); }, render: function() { - var discussionModuleView = new DiscussionModuleView({ - el: this.$el, - readOnly: this.$el.data('read-only') === true, - context: 'standalone' + var discussionInlineView = new DiscussionInlineView({ + el: this.$el }); - discussionModuleView.render(); - discussionModuleView.loadPage(this.$el); + discussionInlineView.render(); return this; } }); diff --git a/lms/static/lms/js/build.js b/lms/static/lms/js/build.js index 228773ff67..2a1b44b360 100644 --- a/lms/static/lms/js/build.js +++ b/lms/static/lms/js/build.js @@ -79,7 +79,7 @@ 'logger': 'empty:', 'utility': 'empty:', 'URI': 'empty:', - 'common/js/discussion/discussion_module_view': 'empty:', + 'common/js/discussion/views/discussion_inline_view': 'empty:', 'modernizr': 'empty', // Don't bundle UI Toolkit helpers as they are loaded into the "edx" namespace diff --git a/lms/static/lms/js/spec/main.js b/lms/static/lms/js/spec/main.js index b8b220c0e1..b012565709 100644 --- a/lms/static/lms/js/spec/main.js +++ b/lms/static/lms/js/spec/main.js @@ -642,7 +642,7 @@ ], exports: 'ThreadResponseView' }, - 'common/js/discussion/discussion_module_view': { + 'common/js/discussion/views/discussion_inline_view': { deps: [ 'jquery', 'underscore', @@ -666,7 +666,7 @@ 'common/js/discussion/views/thread_response_show_view', 'common/js/discussion/views/thread_response_view' ], - exports: 'DiscussionModuleView' + exports: 'DiscussionInlineView' }, 'common/js/spec_helpers/discussion_spec_helper': { deps: [ diff --git a/lms/static/sass/discussion/_discussion.scss b/lms/static/sass/discussion/_discussion.scss index a9b7486131..b0584ec67d 100644 --- a/lms/static/sass/discussion/_discussion.scss +++ b/lms/static/sass/discussion/_discussion.scss @@ -324,12 +324,17 @@ body.discussion { .add_post_btn_container { @include text-align(right); position: relative; - top: -45px; + top: -25px; } .discussion { &.inline-discussion { - padding-top: $baseline * 3; + padding-top: $baseline * 1.5; + + section.threads { + border: 1px solid $forum-color-border; + border-radius: $forum-border-radius; + } } } diff --git a/lms/static/sass/discussion/elements/_navigation.scss b/lms/static/sass/discussion/elements/_navigation.scss index 4c017df08e..d38076d1af 100644 --- a/lms/static/sass/discussion/elements/_navigation.scss +++ b/lms/static/sass/discussion/elements/_navigation.scss @@ -193,6 +193,12 @@ } } +// Overrides underspecific style from courseware css: +// https://github.com/edx/edx-platform/blob/master/lms/static/sass/course/courseware/_courseware.scss#L402 +.course-wrapper .course-content .forum-nav-thread-list li { + margin: 0; +} + .forum-nav-thread { border-bottom: 1px solid $forum-color-border; background-color: $forum-color-background; diff --git a/lms/templates/discussion/_discussion_inline.html b/lms/templates/discussion/_discussion_inline.html index 2d9aca2fab..c23c460ac6 100644 --- a/lms/templates/discussion/_discussion_inline.html +++ b/lms/templates/discussion/_discussion_inline.html @@ -1,6 +1,7 @@ <%page expression_filter="h"/> <%include file="_underscore_templates.html" /> +<%include file="_thread_list_template.html" /> <%! from django.utils.translation import ugettext as _ @@ -21,13 +22,10 @@ from openedx.core.djangolib.js_utils import js_escaped_string diff --git a/lms/templates/discussion/_js_body_dependencies.html b/lms/templates/discussion/_js_body_dependencies.html index d4be582f9b..d10b6918b6 100644 --- a/lms/templates/discussion/_js_body_dependencies.html +++ b/lms/templates/discussion/_js_body_dependencies.html @@ -17,7 +17,7 @@ from openedx.core.djangolib.js_utils import js_escaped_string discussion_classes = [ ['Discussion', 'common/js/discussion/discussion'], ['Content', 'common/js/discussion/content'], - ['DiscussionModuleView', 'common/js/discussion/discussion_module_view'], + ['DiscussionInlineView', 'common/js/discussion/views/discussion_inline_view'], ['DiscussionThreadView', 'common/js/discussion/views/discussion_thread_view'], ['DiscussionThreadListView', 'common/js/discussion/views/discussion_thread_list_view'], ['DiscussionThreadProfileView', 'common/js/discussion/views/discussion_thread_profile_view'], diff --git a/lms/templates/discussion/_thread_list_template.html b/lms/templates/discussion/_thread_list_template.html index 20a2d64170..3afffaaee3 100644 --- a/lms/templates/discussion/_thread_list_template.html +++ b/lms/templates/discussion/_thread_list_template.html @@ -1,7 +1,7 @@ <%page expression_filter="h"/> <%! from django.utils.translation import ugettext as _ %>