diff --git a/js/src/forum/components/DiscussionList.js b/js/src/forum/components/DiscussionList.js
index 0e7ec4f99..4f14e5cc7 100644
--- a/js/src/forum/components/DiscussionList.js
+++ b/js/src/forum/components/DiscussionList.js
@@ -4,6 +4,13 @@ import Button from '../../common/components/Button';
import LoadingIndicator from '../../common/components/LoadingIndicator';
import Placeholder from '../../common/components/Placeholder';
+/**
+ * How many discussions do we show / load per page?
+ *
+ * @type {number}
+ */
+const DISCUSSIONS_PER_PAGE = 20;
+
/**
* The `DiscussionList` component displays a list of discussions.
*
@@ -15,11 +22,11 @@ import Placeholder from '../../common/components/Placeholder';
export default class DiscussionList extends Component {
init() {
/**
- * Whether or not discussion results are loading.
+ * Whether or not discussion results are loading for the next page.
*
* @type {Boolean}
*/
- this.loading = true;
+ this.loadingNext = true;
/**
* Whether or not discussion results are loading for the previous page.
@@ -28,13 +35,6 @@ export default class DiscussionList extends Component {
*/
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.
*
@@ -63,19 +63,12 @@ export default class DiscussionList extends Component {
*/
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) * this.offsetBy;
+ this.offset = (this.page - 1) * DISCUSSIONS_PER_PAGE;
/**
* The discussions in the discussion list.
@@ -97,7 +90,7 @@ export default class DiscussionList extends Component {
view() {
const params = this.props.params;
- if (this.discussions.length === 0 && !this.loading) {
+ if (this.discussions.length === 0 && !this.loadingNext) {
const text = app.translator.trans('core.forum.discussion_list.empty_text');
return
{Placeholder.component({ text })}
;
}
@@ -106,7 +99,7 @@ export default class DiscussionList extends Component {
{this.loadingPrev
? LoadingIndicator.component()
- : this.firstLoadedPage !== 1 &&
{this.getLoadButton(false)}
}
+ : this.firstLoadedPage !== 1 &&
{this.getLoadPrevButton()}
}
{this.discussions.map((discussion) => {
return (
@@ -116,7 +109,9 @@ export default class DiscussionList extends Component {
);
})}
-
{this.loading ? LoadingIndicator.component() : this.moreResults && this.getLoadButton()}
+
+ {this.loadingNext ? LoadingIndicator.component() : this.moreResults && this.getLoadNextButton()}
+
);
}
@@ -169,7 +164,7 @@ export default class DiscussionList extends Component {
*/
refresh(clear = true) {
if (clear) {
- this.loading = true;
+ this.loadingNext = true;
this.discussions = [];
}
@@ -179,7 +174,7 @@ export default class DiscussionList extends Component {
this.parseResults(results);
},
() => {
- this.loading = false;
+ this.loadingNext = false;
m.redraw();
}
);
@@ -206,29 +201,36 @@ export default class DiscussionList extends Component {
}
/**
- * Load the next page of discussion results.
+ * Load the previous page of discussion results.
*
- * @param isNext the page to load is the next page, false for previous page
* @public
*/
- load(isNext = true) {
- if (isNext) {
- this.loading = true;
- this.page = ++this.lastLoadedPage;
- } else if (this.firstLoadedPage !== 1) {
+ loadPrev() {
+ if (this.firstLoadedPage !== 1) {
this.loadingPrev = true;
this.page = --this.firstLoadedPage;
this.addResultsToBeginning = true;
}
- this.loadResults((this.offset = (this.page - 1) * this.offsetBy)).then(this.parseResults.bind(this));
+ this.loadResults((this.offset = (this.page - 1) * DISCUSSIONS_PER_PAGE)).then(this.parseResults.bind(this));
+ }
+
+ /**
+ * Load the next page of discussion results.
+ *
+ * @public
+ */
+ loadNext() {
+ this.loadingNext = true;
+ this.page = ++this.lastLoadedPage;
+
+ this.loadResults((this.offset = (this.page - 1) * DISCUSSIONS_PER_PAGE)).then(this.parseResults.bind(this));
}
/**
* Parse results and append them to the discussion list.
*
* @param {Discussion[]} results
- * @return {Discussion[]}
*/
parseResults(results) {
// If the results need to be added to the beginning of the discussion list
@@ -240,31 +242,35 @@ export default class DiscussionList extends Component {
[].push.apply(this.discussions, results);
}
- this.loading = false;
+ this.loadingNext = 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();
+ this.updateUrl();
+ }
- // Update page parameter in URL
- // not supported in IE
- if (typeof window.URL === 'function') {
- const query = m.route.parseQueryString(document.location.search);
+ /**
+ * Update the "page" parameter in the URL shown to the user.
+ *
+ * Constructs a URL to this discussion with the updated page, then
+ * replaces it into the window's history and our own history stack.
+ */
+ updateUrl() {
+ // Bail out if the browser does not support updating the URL.
+ if (typeof window.URL !== 'function') return;
- if (this.page !== 1) query.page = this.page;
- else delete query.page;
+ const query = m.route.parseQueryString(document.location.search);
+ query.page = this.page;
- const url = new URL(document.location.href);
-
- url.search = m.route.buildQueryString(query);
-
- window.history.replaceState(null, document.title, url);
+ if (this.page === 1) {
+ delete query.page;
}
- return results;
+ const url = new URL(document.location.href);
+ url.search = m.route.buildQueryString(query);
+
+ window.history.replaceState(null, '', url.toString());
}
/**
@@ -292,15 +298,28 @@ export default class DiscussionList extends Component {
}
/**
- * Get the "Load More" or "Load Previous" page buttons
+ * Get the "Load Previous" page button.
*
- * @param isNext
+ * @return {Button}
*/
- getLoadButton(isNext = true) {
+ getLoadPrevButton() {
return Button.component({
- children: app.translator.trans(`core.forum.discussion_list.load_${isNext ? 'more' : 'prev'}_button`),
+ children: app.translator.trans(`core.forum.discussion_list.load_prev_button`),
className: 'Button',
- onclick: this.load.bind(this, isNext),
+ onclick: this.loadPrev.bind(this),
+ });
+ }
+
+ /**
+ * Get the "Load More" page button.
+ *
+ * @return {Button}
+ */
+ getLoadNextButton() {
+ return Button.component({
+ children: app.translator.trans(`core.forum.discussion_list.load_more_button`),
+ className: 'Button',
+ onclick: this.loadNext.bind(this),
});
}
}
diff --git a/less/forum/DiscussionList.less b/less/forum/DiscussionList.less
index 2e2f1453a..f6a0d768d 100644
--- a/less/forum/DiscussionList.less
+++ b/less/forum/DiscussionList.less
@@ -7,7 +7,7 @@
list-style-type: none;
position: relative;
}
-.DiscussionList-loadMore, .DiscussionList-loadPrev {
+.DiscussionList-loadMore {
text-align: center;
margin-top: 10px;
}