mirror of
https://github.com/flarum/framework.git
synced 2025-05-23 23:29:57 +08:00
Extensibility: discussion list params
Also give the root controller the name of the current route so they can easily route back to it
This commit is contained in:
@ -16,19 +16,30 @@ export default class DiscussionList extends Component {
|
|||||||
this.loading = m.prop(true);
|
this.loading = m.prop(true);
|
||||||
this.moreResults = m.prop(false);
|
this.moreResults = m.prop(false);
|
||||||
this.discussions = m.prop([]);
|
this.discussions = m.prop([]);
|
||||||
this.sort = m.prop(this.props.sort || 'recent');
|
|
||||||
this.sortOptions = m.prop([
|
|
||||||
{key: 'recent', value: 'Recent', sort: 'recent'},
|
|
||||||
{key: 'replies', value: 'Replies', sort: '-replies'},
|
|
||||||
{key: 'newest', value: 'Newest', sort: '-created'},
|
|
||||||
{key: 'oldest', value: 'Oldest', sort: 'created'}
|
|
||||||
]);
|
|
||||||
|
|
||||||
this.refresh();
|
this.refresh();
|
||||||
|
|
||||||
app.session.on('loggedIn', this.loggedInHandler = this.refresh.bind(this))
|
app.session.on('loggedIn', this.loggedInHandler = this.refresh.bind(this))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
params() {
|
||||||
|
var params = {};
|
||||||
|
for (var i in this.props.params) {
|
||||||
|
params[i] = this.props.params[i];
|
||||||
|
}
|
||||||
|
params.sort = this.sortMap()[params.sort];
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
sortMap() {
|
||||||
|
return {
|
||||||
|
recent: 'recent',
|
||||||
|
replies: '-replies',
|
||||||
|
newest: '-created',
|
||||||
|
oldest: 'created'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
refresh() {
|
refresh() {
|
||||||
m.startComputation();
|
m.startComputation();
|
||||||
this.loading(true);
|
this.loading(true);
|
||||||
@ -42,26 +53,16 @@ export default class DiscussionList extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
terminalPostType() {
|
terminalPostType() {
|
||||||
return ['newest', 'oldest'].indexOf(this.sort()) !== -1 ? 'start' : 'last'
|
return ['newest', 'oldest'].indexOf(this.props.sort) !== -1 ? 'start' : 'last'
|
||||||
}
|
}
|
||||||
|
|
||||||
countType() {
|
countType() {
|
||||||
return this.sort() === 'replies' ? 'replies' : 'unread';
|
return this.props.sort === 'replies' ? 'replies' : 'unread';
|
||||||
}
|
}
|
||||||
|
|
||||||
loadResults(start) {
|
loadResults(start) {
|
||||||
var self = this;
|
var params = this.params();
|
||||||
|
params.start = start;
|
||||||
var sort = this.sortOptions()[0].sort;
|
|
||||||
this.sortOptions().some(function(option) {
|
|
||||||
if (option.key === self.sort()) {
|
|
||||||
sort = option.sort;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var params = {sort, start};
|
|
||||||
|
|
||||||
return app.store.find('discussions', params);
|
return app.store.find('discussions', params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,10 +98,10 @@ export default class DiscussionList extends Component {
|
|||||||
view() {
|
view() {
|
||||||
return m('div', [
|
return m('div', [
|
||||||
m('ul.discussions-list', [
|
m('ul.discussions-list', [
|
||||||
this.discussions().map(function(discussion) {
|
this.discussions().map(discussion => {
|
||||||
var startUser = discussion.startUser()
|
var startUser = discussion.startUser()
|
||||||
var isUnread = discussion.isUnread()
|
var isUnread = discussion.isUnread()
|
||||||
var displayUnread = this.props.countType !== 'replies' && isUnread
|
var displayUnread = this.countType() !== 'replies' && isUnread
|
||||||
var jumpTo = Math.min(discussion.lastPostNumber(), (discussion.readNumber() || 0) + 1)
|
var jumpTo = Math.min(discussion.lastPostNumber(), (discussion.readNumber() || 0) + 1)
|
||||||
|
|
||||||
var controls = discussion.controls(this).toArray();
|
var controls = discussion.controls(this).toArray();
|
||||||
@ -135,7 +136,7 @@ export default class DiscussionList extends Component {
|
|||||||
m('span.label', displayUnread ? 'unread' : 'replies')
|
m('span.label', displayUnread ? 'unread' : 'replies')
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
}.bind(this))
|
})
|
||||||
]),
|
]),
|
||||||
this.loading()
|
this.loading()
|
||||||
? LoadingIndicator.component()
|
? LoadingIndicator.component()
|
||||||
@ -159,7 +160,7 @@ export default class DiscussionList extends Component {
|
|||||||
items.add('terminalPost',
|
items.add('terminalPost',
|
||||||
TerminalPost.component({
|
TerminalPost.component({
|
||||||
discussion,
|
discussion,
|
||||||
lastPost: this.props.terminalPostType !== 'start'
|
lastPost: this.terminalPostType() !== 'start'
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -18,15 +18,17 @@ export default class IndexPage extends Component {
|
|||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
|
var params = this.params();
|
||||||
if (app.cache.discussionList) {
|
if (app.cache.discussionList) {
|
||||||
if (app.cache.discussionList.props.sort !== m.route.param('sort')) {
|
Object.keys(params).some(key => {
|
||||||
|
if (app.cache.discussionList.props.params[key] !== params[key]) {
|
||||||
app.cache.discussionList = null;
|
app.cache.discussionList = null;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (!app.cache.discussionList) {
|
if (!app.cache.discussionList) {
|
||||||
app.cache.discussionList = new DiscussionList({
|
app.cache.discussionList = new DiscussionList({params});
|
||||||
sort: m.route.param('sort')
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
app.history.push('index');
|
app.history.push('index');
|
||||||
@ -34,10 +36,34 @@ export default class IndexPage extends Component {
|
|||||||
app.composer.minimize();
|
app.composer.minimize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Params that stick between filter changes
|
||||||
|
*/
|
||||||
|
stickyParams() {
|
||||||
|
return {
|
||||||
|
sort: m.route.param('sort'),
|
||||||
|
show: m.route.param('show'),
|
||||||
|
q: m.route.param('q')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Params which are passed to the DiscussionList
|
||||||
|
*/
|
||||||
|
params() {
|
||||||
|
var params = this.stickyParams();
|
||||||
|
params.filter = m.route.param('filter');
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
reorder(sort) {
|
reorder(sort) {
|
||||||
var filter = m.route.param('filter') || '';
|
var params = this.params();
|
||||||
var params = sort !== 'recent' ? {sort} : {};
|
if (sort === 'recent') {
|
||||||
m.route(app.route('index.filter', {filter}, params));
|
delete params.sort;
|
||||||
|
} else {
|
||||||
|
params.sort = sort;
|
||||||
|
}
|
||||||
|
m.route(app.route(this.props.routeName, params));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,6 +73,11 @@ export default class IndexPage extends Component {
|
|||||||
@return void
|
@return void
|
||||||
*/
|
*/
|
||||||
view() {
|
view() {
|
||||||
|
var sortOptions = {};
|
||||||
|
for (var i in app.cache.discussionList.sortMap()) {
|
||||||
|
sortOptions[i] = i.substr(0, 1).toUpperCase()+i.substr(1);
|
||||||
|
}
|
||||||
|
|
||||||
return m('div.index-area', {config: this.onload.bind(this)}, [
|
return m('div.index-area', {config: this.onload.bind(this)}, [
|
||||||
WelcomeHero.component(),
|
WelcomeHero.component(),
|
||||||
m('div.container', [
|
m('div.container', [
|
||||||
@ -57,8 +88,8 @@ export default class IndexPage extends Component {
|
|||||||
m('div.index-toolbar', [
|
m('div.index-toolbar', [
|
||||||
m('div.index-toolbar-view', [
|
m('div.index-toolbar-view', [
|
||||||
SelectInput.component({
|
SelectInput.component({
|
||||||
options: app.cache.discussionList.sortOptions(),
|
options: sortOptions,
|
||||||
value: app.cache.discussionList.sort(),
|
value: m.route.param('sort'),
|
||||||
onchange: this.reorder.bind(this)
|
onchange: this.reorder.bind(this)
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
|
@ -5,7 +5,7 @@ export default class SelectInput extends Component {
|
|||||||
view(ctrl) {
|
view(ctrl) {
|
||||||
return m('span.select-input', [
|
return m('span.select-input', [
|
||||||
m('select.form-control', {onchange: m.withAttr('value', this.props.onchange.bind(ctrl)), value: this.props.value}, [
|
m('select.form-control', {onchange: m.withAttr('value', this.props.onchange.bind(ctrl)), value: this.props.value}, [
|
||||||
this.props.options.map(function(option) { return m('option', {value: option.key}, option.value) })
|
Object.keys(this.props.options).map(key => m('option', {value: key}, this.props.options[key]))
|
||||||
]),
|
]),
|
||||||
icon('sort')
|
icon('sort')
|
||||||
])
|
])
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
export default function mapRoutes(routes) {
|
export default function mapRoutes(routes) {
|
||||||
var map = {};
|
var map = {};
|
||||||
for (var r in routes) {
|
for (var r in routes) {
|
||||||
|
routes[r][1].props.routeName = r;
|
||||||
map[routes[r][0]] = routes[r][1];
|
map[routes[r][0]] = routes[r][1];
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
|
Reference in New Issue
Block a user