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/utils.js b/common/static/common/js/discussion/utils.js index 44755e98d7..83ff8bcd67 100644 --- a/common/static/common/js/discussion/utils.js +++ b/common/static/common/js/discussion/utils.js @@ -184,10 +184,8 @@ if (!params.error) { params.error = function() { self.discussionAlert( - gettext('Sorry'), - gettext( - 'We had some trouble processing your request. Please ensure you have copied any ' + - 'unsaved work and then reload the page.') + gettext('Error'), + gettext('Your request could not be processed. Refresh the page and try again.') ); }; } @@ -223,7 +221,7 @@ self = this; if (errorMsg) { safeAjaxParams.error = function() { - return self.discussionAlert(gettext('Sorry'), errorMsg); + return self.discussionAlert(gettext('Error'), errorMsg); }; } undo = _.pick(model.attributes, _.keys(updates)); @@ -276,7 +274,7 @@ } } } else { - $errorItem = makeErrorElem('We had some trouble processing your request. Please try again.', 0); + $errorItem = makeErrorElem('Your request could not be processed. Refresh the page and try again.', 0); // eslint-disable-line max-len edx.HtmlUtils.append(errorsField, $errorItem); } diff --git a/common/static/common/js/discussion/views/discussion_content_view.js b/common/static/common/js/discussion/views/discussion_content_view.js index 19e965e143..3b00c3e257 100644 --- a/common/static/common/js/discussion/views/discussion_content_view.js +++ b/common/static/common/js/discussion/views/discussion_content_view.js @@ -1,4 +1,4 @@ -/* globals DiscussionContentView, DiscussionUtil */ +/* globals _, Backbone, DiscussionContentView, DiscussionUtil */ (function() { 'use strict'; var __hasProp = {}.hasOwnProperty, @@ -148,22 +148,24 @@ return _results; }; - DiscussionContentView.prototype.makeWmdEditor = function(cls_identifier) { + DiscussionContentView.prototype.makeWmdEditor = function(classIdentifier) { if (!this.$el.find('.wmd-panel').length) { - return DiscussionUtil.makeWmdEditor(this.$el, $.proxy(this.$, this), cls_identifier); + return DiscussionUtil.makeWmdEditor(this.$el, $.proxy(this.$, this), classIdentifier); + } else { + return null; } }; - DiscussionContentView.prototype.getWmdEditor = function(cls_identifier) { - return DiscussionUtil.getWmdEditor(this.$el, $.proxy(this.$, this), cls_identifier); + DiscussionContentView.prototype.getWmdEditor = function(classIdentifier) { + return DiscussionUtil.getWmdEditor(this.$el, $.proxy(this.$, this), classIdentifier); }; - DiscussionContentView.prototype.getWmdContent = function(cls_identifier) { - return DiscussionUtil.getWmdContent(this.$el, $.proxy(this.$, this), cls_identifier); + DiscussionContentView.prototype.getWmdContent = function(classIdentifier) { + return DiscussionUtil.getWmdContent(this.$el, $.proxy(this.$, this), classIdentifier); }; - DiscussionContentView.prototype.setWmdContent = function(cls_identifier, text) { - return DiscussionUtil.setWmdContent(this.$el, $.proxy(this.$, this), cls_identifier, text); + DiscussionContentView.prototype.setWmdContent = function(classIdentifier, text) { + return DiscussionUtil.setWmdContent(this.$el, $.proxy(this.$, this), classIdentifier, text); }; DiscussionContentView.prototype.initialize = function() { @@ -171,7 +173,7 @@ this.model.bind('change', this.renderPartialAttrs, this); return this.listenTo(this.model, 'change:endorsed', function() { if (self.model instanceof Comment) { - return self.trigger('comment:endorse'); + self.trigger('comment:endorse'); } }); }; @@ -330,7 +332,7 @@ DiscussionContentShowView.prototype.handleSecondaryActionEscape = function(event) { if (event.keyCode === 27) { this.toggleSecondaryActions(event); - return this.$('.action-more').focus(); + this.$('.action-more').focus(); } }; @@ -338,23 +340,23 @@ var self = this; return setTimeout(function() { if (self.secondaryActionsExpanded && self.$('.actions-dropdown :focus').length === 0) { - return self.toggleSecondaryActions(event); + self.toggleSecondaryActions(event); } }, 10); }; DiscussionContentShowView.prototype.toggleFollow = function(event) { - var is_subscribing, msg, url; + var isSubscribing, msg, url; event.preventDefault(); - is_subscribing = !this.model.get('subscribed'); - url = this.model.urlFor(is_subscribing ? 'follow' : 'unfollow'); - if (is_subscribing) { - msg = gettext('We had some trouble subscribing you to this thread. Please try again.'); + isSubscribing = !this.model.get('subscribed'); + url = this.model.urlFor(isSubscribing ? 'follow' : 'unfollow'); + if (isSubscribing) { + msg = gettext('You could not be subscribed to this post. Refresh the page and try again.'); } else { - msg = gettext('We had some trouble unsubscribing you from this thread. Please try again.'); + msg = gettext('You could not be unsubscribed from this post. Refresh the page and try again.'); } return DiscussionUtil.updateWithUndo(this.model, { - 'subscribed': is_subscribing + subscribed: isSubscribing }, { url: url, type: 'POST', @@ -363,30 +365,30 @@ }; DiscussionContentShowView.prototype.toggleEndorse = function(event) { - var beforeFunc, is_endorsing, msg, updates, url, + var isEndorsing, msg, updates, url, self = this; event.preventDefault(); - is_endorsing = !this.model.get('endorsed'); + isEndorsing = !this.model.get('endorsed'); url = this.model.urlFor('endorse'); updates = { - endorsed: is_endorsing, - endorsement: is_endorsing ? { + endorsed: isEndorsing, + endorsement: isEndorsing ? { username: DiscussionUtil.getUser().get('username'), user_id: DiscussionUtil.getUser().id, time: new Date().toISOString() } : null }; if (this.model.get('thread').get('thread_type') === 'question') { - if (is_endorsing) { - msg = gettext('We had some trouble marking this response as an answer. Please try again.'); + if (isEndorsing) { + msg = gettext('This response could not be marked as an answer. Refresh the page and try again.'); // eslint-disable-line max-len } else { - msg = gettext('We had some trouble removing this response as an answer. Please try again.'); + msg = gettext('This response could not be unmarked as an answer. Refresh the page and try again.'); // eslint-disable-line max-len } } else { - if (is_endorsing) { - msg = gettext('We had some trouble marking this response endorsed. Please try again.'); + if (isEndorsing) { + msg = gettext('This response could not be marked as endorsed. Refresh the page and try again.'); } else { - msg = gettext('We had some trouble removing this endorsement. Please try again.'); + msg = gettext('This response could not be unendorsed. Refresh the page and try again.'); } } return DiscussionUtil.updateWithUndo( @@ -395,7 +397,7 @@ { url: url, type: 'POST', - data: {endorsed: is_endorsing}, + data: {endorsed: isEndorsing}, $elem: $(event.currentTarget) }, msg, @@ -404,22 +406,22 @@ }; DiscussionContentShowView.prototype.toggleVote = function(event) { - var is_voting, updates, url, user, + var isVoting, updates, url, user, self = this; event.preventDefault(); user = DiscussionUtil.getUser(); - is_voting = !user.voted(this.model); - url = this.model.urlFor(is_voting ? 'upvote' : 'unvote'); + isVoting = !user.voted(this.model); + url = this.model.urlFor(isVoting ? 'upvote' : 'unvote'); updates = { - upvoted_ids: (is_voting ? _.union : _.difference)(user.get('upvoted_ids'), [this.model.id]) + upvoted_ids: (isVoting ? _.union : _.difference)(user.get('upvoted_ids'), [this.model.id]) }; if (!$(event.target.closest('.actions-item')).hasClass('is-disabled')) { return DiscussionUtil.updateWithUndo(user, updates, { url: url, type: 'POST', $elem: $(event.currentTarget) - }, gettext('We had some trouble saving your vote. Please try again.')).done(function() { - if (is_voting) { + }, gettext('This vote could not be processed. Refresh the page and try again.')).done(function() { + if (isVoting) { return self.model.vote(); } else { return self.model.unvote(); @@ -429,17 +431,17 @@ }; DiscussionContentShowView.prototype.togglePin = function(event) { - var is_pinning, msg, url; + var isPinning, msg, url; event.preventDefault(); - is_pinning = !this.model.get('pinned'); - url = this.model.urlFor(is_pinning ? 'pinThread' : 'unPinThread'); - if (is_pinning) { - msg = gettext('We had some trouble pinning this thread. Please try again.'); + isPinning = !this.model.get('pinned'); + url = this.model.urlFor(isPinning ? 'pinThread' : 'unPinThread'); + if (isPinning) { + msg = gettext('This post could not be pinned. Refresh the page and try again.'); } else { - msg = gettext('We had some trouble unpinning this thread. Please try again.'); + msg = gettext('This post could not be unpinned. Refresh the page and try again.'); } return DiscussionUtil.updateWithUndo(this.model, { - pinned: is_pinning + pinned: isPinning }, { url: url, type: 'POST', @@ -448,18 +450,18 @@ }; DiscussionContentShowView.prototype.toggleReport = function(event) { - var is_flagging, msg, updates, url; + var isFlagging, msg, updates, url; event.preventDefault(); if (this.model.isFlagged()) { - is_flagging = false; - msg = gettext('We had some trouble removing your flag on this post. Please try again.'); + isFlagging = false; + msg = gettext('This post could not be flagged for abuse. Refresh the page and try again.'); } else { - is_flagging = true; - msg = gettext('We had some trouble reporting this post. Please try again.'); + isFlagging = true; + msg = gettext('This post could not be unflagged for abuse. Refresh the page and try again.'); } - url = this.model.urlFor(is_flagging ? 'flagAbuse' : 'unFlagAbuse'); + url = this.model.urlFor(isFlagging ? 'flagAbuse' : 'unFlagAbuse'); updates = { - abuse_flaggers: (is_flagging ? _.union : _.difference)( + abuse_flaggers: (isFlagging ? _.union : _.difference)( this.model.get('abuse_flaggers'), [DiscussionUtil.getUser().id] ) }; @@ -471,16 +473,16 @@ }; DiscussionContentShowView.prototype.toggleClose = function(event) { - var is_closing, msg, updates; + var isClosing, msg, updates; event.preventDefault(); - is_closing = !this.model.get('closed'); - if (is_closing) { - msg = gettext('We had some trouble closing this thread. Please try again.'); + isClosing = !this.model.get('closed'); + if (isClosing) { + msg = gettext('This post could not be closed. Refresh the page and try again.'); } else { - msg = gettext('We had some trouble reopening this thread. Please try again.'); + msg = gettext('This post could not be reopened. Refresh the page and try again.'); } updates = { - closed: is_closing + closed: isClosing }; return DiscussionUtil.updateWithUndo(this.model, updates, { url: this.model.urlFor('close'), 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..7a44a6571a --- /dev/null +++ b/common/static/common/js/discussion/views/discussion_inline_view.js @@ -0,0 +1,238 @@ +/* globals + _, Backbone, Content, Discussion, DiscussionUtil, DiscussionUser, DiscussionCourseSettings, + DiscussionThreadListView, DiscussionThreadView, 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', + 'click .all-posts-btn': 'navigateToAllPosts', + keydown: 'handleKeydown', + 'keydown .new-post-btn': function(event) { + return DiscussionUtil.activateOnSpace(event, this.toggleNewPost); + } + }, + + page_re: /\?discussion_page=(\d+)/, + + initialize: function(options) { + var match; + + this.$el = options.el; + this.readOnly = options.readOnly; + this.showByDefault = options.showByDefault || false; + this.toggleDiscussionBtn = this.$('.discussion-show'); + this.listenTo(this.model, 'change', this.render); + this.escKey = 27; + + match = this.page_re.exec(window.location.href); + if (match) { + this.page = parseInt(match[1], 10); + } else { + this.page = 1; + } + + // By default the view is displayed in a hidden state. If you want it to be shown by default (e.g. in Teams) + // pass showByDefault as an option. This code will open it on initialization. + if (this.showByDefault) { + this.toggleDiscussion(); + } + }, + + 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 discussionHtml, + 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(undefined, {pages: response.num_pages}); + this.discussion.reset(response.discussion_data, { + silent: false + }); + + discussionHtml = edx.HtmlUtils.template($('#inline-discussion-template').html())({ + threads: response.discussion_data, + read_only: this.readOnly, + discussionId: discussionId + }); + + if (this.$('section.discussion').length) { + edx.HtmlUtils.setHtml(this.$el, discussionHtml); + this.$('section.discussion').replaceWith(edx.HtmlUtils.ensureHtml(discussionHtml).toString()); + } else { + edx.HtmlUtils.append(this.$el, discussionHtml); + } + + this.threadListView = new DiscussionThreadListView({ + el: this.$('.inline-threads'), + collection: self.discussion, + courseSettings: self.course_settings, + hideRefineBar: true // TODO: re-enable the search/filter bar when it works correctly + }); + + this.threadListView.render(); + + this.threadListView.on('thread:selected', _.bind(this.navigateToThread, this)); + + 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:createPost', this.onNewPostCreated); + 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.removeClass('is-hidden').focus(); + } + + // Hide the thread view initially + this.$('.inline-thread').addClass('is-hidden'); + }, + + navigateToThread: function(threadId) { + var thread = this.discussion.get(threadId); + this.threadView = new DiscussionThreadView({ + el: this.$('.forum-content'), + model: thread, + mode: 'inline', + course_settings: this.course_settings + }); + this.threadView.render(); + this.listenTo(this.threadView.showView, 'thread:_delete', this.navigateToAllPosts); + this.threadListView.$el.addClass('is-hidden'); + this.$('.inline-thread').removeClass('is-hidden'); + }, + + navigateToAllPosts: function() { + // Hide the inline thread section + this.$('.inline-thread').addClass('is-hidden'); + + // Delete the thread view + this.threadView.$el.empty().off(); + this.threadView.stopListening(); + this.threadView = null; + + // Show the thread list view + this.threadListView.$el.removeClass('is-hidden'); + + // Set focus to thread list item that was saved as active + this.threadListView.$('.is-active').focus(); + }, + + toggleDiscussion: function() { + var self = this; + + if (this.showed) { + this.hideDiscussion(); + } else { + this.toggleDiscussionBtn.addClass('shown'); + this.toggleDiscussionBtn.find('.button-text').text(gettext('Hide Discussion')); + if (this.retrieved) { + this.$('section.discussion').removeClass('is-hidden'); + this.showed = true; + } else { + this.loadDiscussions(this.$el, function() { + self.hideDiscussion(); + DiscussionUtil.discussionAlert( + gettext('Error'), + gettext('This discussion could not be loaded. Refresh the page and try again.') + ); + }); + } + } + }, + + hideDiscussion: function() { + this.$('section.discussion').addClass('is-hidden'); + this.toggleDiscussionBtn.removeClass('shown'); + this.toggleDiscussionBtn.find('.button-text').text(gettext('Show Discussion')); + this.showed = false; + }, + + toggleNewPost: function(event) { + event.preventDefault(); + if (!this.newPostForm) { + this.toggleDiscussion(); + this.isWaitingOnNewPost = true; + return; + } + if (this.showed) { + this.$('section.discussion').find('.inline-discussion-thread-container').addClass('is-hidden'); + this.$('section.discussion').find('.add_post_btn_container').addClass('is-hidden'); + this.newPostForm.removeClass('is-hidden'); + } + this.newPostView.$el.removeClass('is-hidden'); + this.toggleDiscussionBtn.addClass('shown'); + this.toggleDiscussionBtn.find('.button-text').text(gettext('Hide Discussion')); + this.showed = true; + }, + + onNewPostCreated: function() { + this.navigateToAllPosts(); + this.hideNewPost(); + }, + + hideNewPost: function() { + this.$('section.discussion').find('.inline-discussion-thread-container').removeClass('is-hidden'); + this.$('section.discussion').find('.add_post_btn_container') + .removeClass('is-hidden') + .focus(); + this.newPostForm.addClass('is-hidden'); + }, + + handleKeydown: function(event) { + var keyCode = event.keyCode; + if (keyCode === this.escKey) { + this.$('section.discussion').find('.cancel').trigger('click'); + } + } + }); +}).call(window); diff --git a/common/static/common/js/discussion/views/discussion_thread_list_view.js b/common/static/common/js/discussion/views/discussion_thread_list_view.js index c6a8c379d0..ef9cf793a2 100644 --- a/common/static/common/js/discussion/views/discussion_thread_list_view.js +++ b/common/static/common/js/discussion/views/discussion_thread_list_view.js @@ -91,6 +91,8 @@ DiscussionThreadListView.prototype.initialize = function(options) { var self = this; this.courseSettings = options.courseSettings; + this.hideRefineBar = options.hideRefineBar; + this.supportsActiveThread = options.supportsActiveThread; this.displayedCollection = new Discussion(this.collection.models, { pages: this.collection.pages }); @@ -107,7 +109,7 @@ this.boardName = null; this.current_search = ''; this.mode = 'all'; - this.showThreadPreview = options.showThreadPreview; + this.showThreadPreview = true; this.searchAlertCollection = new Backbone.Collection([], { model: Backbone.Model }); @@ -164,7 +166,7 @@ active = $currentElement.has('.forum-nav-thread-link.is-active').length !== 0; $currentElement.replaceWith($content); this.showMetadataAccordingToSort(); - if (active) { + if (this.supportsActiveThread && active) { this.setActiveThread(threadId); } }; @@ -220,6 +222,9 @@ } this.showMetadataAccordingToSort(); this.renderMorePages(); + if (this.hideRefineBar) { + this.$('.forum-nav-refine-bar').addClass('is-hidden'); + } this.trigger('threads:rendered'); }; @@ -309,7 +314,8 @@ error = function() { self.renderThreads(); DiscussionUtil.discussionAlert( - gettext('Sorry'), gettext('We had some trouble loading more threads. Please try again.') + gettext('Error'), + gettext('Additional posts could not be loaded. Refresh the page and try again.') ); }; return this.collection.retrieveAnotherPage(this.mode, options, { @@ -346,7 +352,9 @@ DiscussionThreadListView.prototype.threadSelected = function(e) { var threadId; threadId = $(e.target).closest('.forum-nav-thread').attr('data-id'); - this.setActiveThread(threadId); + if (this.supportsActiveThread) { + this.setActiveThread(threadId); + } this.trigger('thread:selected', threadId); return false; }; @@ -478,7 +486,7 @@ element, edx.HtmlUtils.joinHtml( edx.HtmlUtils.HTML("