From eac5390058896d31363841d16f6814b54e282f56 Mon Sep 17 00:00:00 2001 From: David Sevilla Martin Date: Sat, 16 Nov 2019 09:50:58 -0500 Subject: [PATCH] Add load previous page button, fix IE issues --- js/src/forum/components/DiscussionList.js | 109 +++++++++++++++++----- less/forum/DiscussionList.less | 2 +- 2 files changed, 89 insertions(+), 22 deletions(-) diff --git a/js/src/forum/components/DiscussionList.js b/js/src/forum/components/DiscussionList.js index 12f5cb492..0e7ec4f99 100644 --- a/js/src/forum/components/DiscussionList.js +++ b/js/src/forum/components/DiscussionList.js @@ -21,6 +21,20 @@ export default class DiscussionList extends Component { */ this.loading = true; + /** + * Whether or not discussion results are loading for the previous page. + * + * @type {Boolean} + */ + this.loadingPrev = false; + + /** + * Whether or not there are previous results that can be loaded + * + * @type {boolean} + */ + this.previousResults = false; + /** * Whether or not there are more results that can be loaded. * @@ -30,15 +44,38 @@ export default class DiscussionList extends Component { /** * Current page in discussion list + * + * @type {number} */ this.page = Number(m.route.param('page')) || 1; + /** + * First page loaded in discussion list + * + * @type {number} + */ + this.firstLoadedPage = this.page; + + /** + * Last page loaded in discussion list + * + * @type {number} + */ + this.lastLoadedPage = this.page; + + /** + * Discussions per page + * + * @type {number} + */ + this.offsetBy = 20; + /** * Number of discussions to offset for pagination * * @type {number} */ - this.offset = (this.page - 1) * 20; + this.offset = (this.page - 1) * this.offsetBy; /** * The discussions in the discussion list. @@ -47,22 +84,18 @@ export default class DiscussionList extends Component { */ this.discussions = []; + /** + * When getting more discussions, put the new discussions at the top of the discussion list + * + * @type {boolean} + */ + this.addResultsToBeginning = false; + this.refresh(); } view() { const params = this.props.params; - let loading; - - if (this.loading) { - loading = LoadingIndicator.component(); - } else if (this.moreResults) { - loading = Button.component({ - children: app.translator.trans('core.forum.discussion_list.load_more_button'), - className: 'Button', - onclick: this.loadMore.bind(this), - }); - } if (this.discussions.length === 0 && !this.loading) { const text = app.translator.trans('core.forum.discussion_list.empty_text'); @@ -71,6 +104,9 @@ export default class DiscussionList extends Component { return (
+ {this.loadingPrev + ? LoadingIndicator.component() + : this.firstLoadedPage !== 1 &&
{this.getLoadButton(false)}
} -
{loading}
+
{this.loading ? LoadingIndicator.component() : this.moreResults && this.getLoadButton()}
); } @@ -172,14 +208,20 @@ export default class DiscussionList extends Component { /** * Load the next page of discussion results. * + * @param isNext the page to load is the next page, false for previous page * @public */ - loadMore() { - this.loading = true; + load(isNext = true) { + if (isNext) { + this.loading = true; + this.page = ++this.lastLoadedPage; + } else if (this.firstLoadedPage !== 1) { + this.loadingPrev = true; + this.page = --this.firstLoadedPage; + this.addResultsToBeginning = true; + } - this.page++; - - this.loadResults((this.offset += 20)).then(this.parseResults.bind(this)); + this.loadResults((this.offset = (this.page - 1) * this.offsetBy)).then(this.parseResults.bind(this)); } /** @@ -189,19 +231,31 @@ export default class DiscussionList extends Component { * @return {Discussion[]} */ parseResults(results) { - [].push.apply(this.discussions, results); + // If the results need to be added to the beginning of the discussion list + // do so, and reset the value for the variable keeping track of this necessity + if (this.addResultsToBeginning) { + [].unshift.apply(this.discussions, results); + this.addResultsToBeginning = false; + } else { + [].push.apply(this.discussions, results); + } this.loading = false; + this.loadingPrev = false; + this.previousResults = !!results.payload.links.prev; this.moreResults = !!results.payload.links.next; // Construct a URL to this discussion with the updated page, then // replace it into the window's history and our own history stack. m.lazyRedraw(); - const query = m.route.parseQueryString(document.location.search); + // Update page parameter in URL + // not supported in IE + if (typeof window.URL === 'function') { + const query = m.route.parseQueryString(document.location.search); - if (this.page !== query.page) { if (this.page !== 1) query.page = this.page; + else delete query.page; const url = new URL(document.location.href); @@ -236,4 +290,17 @@ export default class DiscussionList extends Component { addDiscussion(discussion) { this.discussions.unshift(discussion); } + + /** + * Get the "Load More" or "Load Previous" page buttons + * + * @param isNext + */ + getLoadButton(isNext = true) { + return Button.component({ + children: app.translator.trans(`core.forum.discussion_list.load_${isNext ? 'more' : 'prev'}_button`), + className: 'Button', + onclick: this.load.bind(this, isNext), + }); + } } diff --git a/less/forum/DiscussionList.less b/less/forum/DiscussionList.less index f6a0d768d..2e2f1453a 100644 --- a/less/forum/DiscussionList.less +++ b/less/forum/DiscussionList.less @@ -7,7 +7,7 @@ list-style-type: none; position: relative; } -.DiscussionList-loadMore { +.DiscussionList-loadMore, .DiscussionList-loadPrev { text-align: center; margin-top: 10px; }