mirror of
https://github.com/flarum/core.git
synced 2025-08-13 20:04:24 +02:00
Compare commits
3 Commits
as/search_
...
ds/1820-se
Author | SHA1 | Date | |
---|---|---|---|
|
6e8999090e | ||
|
eac5390058 | ||
|
b321585ee8 |
@@ -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,18 @@ 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.
|
||||
*
|
||||
* @type {Boolean}
|
||||
*/
|
||||
this.loadingPrev = false;
|
||||
|
||||
/**
|
||||
* Whether or not there are more results that can be loaded.
|
||||
@@ -28,6 +42,34 @@ export default class DiscussionList extends Component {
|
||||
*/
|
||||
this.moreResults = false;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Number of discussions to offset for pagination
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
this.offset = (this.page - 1) * DISCUSSIONS_PER_PAGE;
|
||||
|
||||
/**
|
||||
* The discussions in the discussion list.
|
||||
*
|
||||
@@ -35,30 +77,29 @@ 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) {
|
||||
if (this.discussions.length === 0 && !this.loadingNext) {
|
||||
const text = app.translator.trans('core.forum.discussion_list.empty_text');
|
||||
return <div className="DiscussionList">{Placeholder.component({ text })}</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={'DiscussionList' + (this.props.params.q ? ' DiscussionList--searchResults' : '')}>
|
||||
{this.loadingPrev
|
||||
? LoadingIndicator.component()
|
||||
: this.firstLoadedPage !== 1 && <div className="DiscussionList-loadMore">{this.getLoadPrevButton()}</div>}
|
||||
<ul className="DiscussionList-discussions">
|
||||
{this.discussions.map((discussion) => {
|
||||
return (
|
||||
@@ -68,7 +109,9 @@ export default class DiscussionList extends Component {
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
<div className="DiscussionList-loadMore">{loading}</div>
|
||||
<div className="DiscussionList-loadMore">
|
||||
{this.loadingNext ? LoadingIndicator.component() : this.moreResults && this.getLoadNextButton()}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -121,7 +164,7 @@ export default class DiscussionList extends Component {
|
||||
*/
|
||||
refresh(clear = true) {
|
||||
if (clear) {
|
||||
this.loading = true;
|
||||
this.loadingNext = true;
|
||||
this.discussions = [];
|
||||
}
|
||||
|
||||
@@ -131,7 +174,7 @@ export default class DiscussionList extends Component {
|
||||
this.parseResults(results);
|
||||
},
|
||||
() => {
|
||||
this.loading = false;
|
||||
this.loadingNext = false;
|
||||
m.redraw();
|
||||
}
|
||||
);
|
||||
@@ -140,10 +183,10 @@ export default class DiscussionList extends Component {
|
||||
/**
|
||||
* Load a new page of discussion results.
|
||||
*
|
||||
* @param {Integer} offset The index to start the page at.
|
||||
* @param {Number} offset The index to start the page at.
|
||||
* @return {Promise}
|
||||
*/
|
||||
loadResults(offset) {
|
||||
loadResults(offset = this.offset) {
|
||||
const preloadedDiscussions = app.preloadedApiDocument();
|
||||
|
||||
if (preloadedDiscussions) {
|
||||
@@ -157,32 +200,77 @@ export default class DiscussionList extends Component {
|
||||
return app.store.find('discussions', params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the previous page of discussion results.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
loadPrev() {
|
||||
if (this.firstLoadedPage !== 1) {
|
||||
this.loadingPrev = true;
|
||||
this.page = --this.firstLoadedPage;
|
||||
this.addResultsToBeginning = true;
|
||||
}
|
||||
|
||||
this.loadResults((this.offset = (this.page - 1) * DISCUSSIONS_PER_PAGE)).then(this.parseResults.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the next page of discussion results.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
loadMore() {
|
||||
this.loading = true;
|
||||
loadNext() {
|
||||
this.loadingNext = true;
|
||||
this.page = ++this.lastLoadedPage;
|
||||
|
||||
this.loadResults(this.discussions.length).then(this.parseResults.bind(this));
|
||||
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) {
|
||||
[].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.loadingNext = false;
|
||||
this.loadingPrev = false;
|
||||
this.moreResults = !!results.payload.links.next;
|
||||
|
||||
m.lazyRedraw();
|
||||
this.updateUrl();
|
||||
}
|
||||
|
||||
return results;
|
||||
/**
|
||||
* 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;
|
||||
|
||||
const query = m.route.parseQueryString(document.location.search);
|
||||
query.page = this.page;
|
||||
|
||||
if (this.page === 1) {
|
||||
delete query.page;
|
||||
}
|
||||
|
||||
const url = new URL(document.location.href);
|
||||
url.search = m.route.buildQueryString(query);
|
||||
|
||||
window.history.replaceState(null, '', url.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -208,4 +296,30 @@ export default class DiscussionList extends Component {
|
||||
addDiscussion(discussion) {
|
||||
this.discussions.unshift(discussion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the "Load Previous" page button.
|
||||
*
|
||||
* @return {Button}
|
||||
*/
|
||||
getLoadPrevButton() {
|
||||
return Button.component({
|
||||
children: app.translator.trans(`core.forum.discussion_list.load_prev_button`),
|
||||
className: 'Button',
|
||||
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),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user