ES6: Convert route builders to initializer

Remove deprecated `Discourse.addInitializer`
This commit is contained in:
Robin Ward 2014-07-02 14:07:30 -04:00
parent 3cb74577a3
commit 4592916026
5 changed files with 192 additions and 226 deletions

View File

@ -100,20 +100,6 @@ window.Discourse = Ember.Application.createWithMixins(Discourse.Ajax, {
if(this.get('loginRequired')) { route.transitionTo('login'); }
},
/**
Add an initializer hook for after the Discourse Application starts up.
@method addInitializer
@param {Function} init the initializer to add.
@param {Boolean} immediate whether to execute the function right away.
Default is false, for next run loop. If unsure, use false.
**/
addInitializer: function(init, immediate) {
Em.warn("`Discouse.addInitializer` is deprecated. Export an Ember initializer instead.");
Discourse.initializers = Discourse.initializers || [];
Discourse.initializers.push({fn: init, immediate: !!immediate});
},
/**
Start up the Discourse application by running all the initializers we've defined.
@ -132,20 +118,6 @@ window.Discourse = Ember.Application.createWithMixins(Discourse.Ajax, {
}
});
var initializers = this.initializers;
if (initializers) {
var self = this;
initializers.forEach(function (init) {
if (init.immediate) {
init.fn.call(self);
} else {
Em.run.next(function() {
init.fn.call(self);
});
}
});
}
},
requiresRefresh: function(){

View File

@ -0,0 +1,26 @@
import buildCategoryRoute from 'discourse/routes/build-category-route';
import buildTopicRoute from 'discourse/routes/build-topic-route';
export default {
name: 'dynamic-route-builders',
initialize: function(container, app) {
app.DiscoveryCategoryRoute = buildCategoryRoute('latest');
app.DiscoveryParentCategoryRoute = buildCategoryRoute('latest');
app.DiscoveryCategoryNoneRoute = buildCategoryRoute('latest', {no_subcategories: true});
Discourse.Site.currentProp('filters').forEach(function(filter) {
app["Discovery" + filter.capitalize() + "Controller"] = Discourse.DiscoverySortableController.extend();
app["Discovery" + filter.capitalize() + "Route"] = buildTopicRoute(filter);
app["Discovery" + filter.capitalize() + "CategoryRoute"] = buildCategoryRoute(filter);
app["Discovery" + filter.capitalize() + "CategoryNoneRoute"] = buildCategoryRoute(filter, {no_subcategories: true});
});
Discourse.Site.currentProp('periods').forEach(function(period) {
app["DiscoveryTop" + period.capitalize() + "Controller"] = Discourse.DiscoverySortableController.extend();
app["DiscoveryTop" + period.capitalize() + "Route"] = buildTopicRoute('top/' + period);
app["DiscoveryTop" + period.capitalize() + "CategoryRoute"] = buildCategoryRoute('top/' + period);
app["DiscoveryTop" + period.capitalize() + "CategoryNoneRoute"] = buildCategoryRoute('top/' + period, {no_subcategories: true});
});
}
};

View File

@ -0,0 +1,84 @@
// A helper function to create a category route with parameters
export default function(filter, params) {
return Discourse.Route.extend({
model: function(params) {
return Discourse.Category.findBySlug(params.slug, params.parentSlug);
},
afterModel: function(model, transaction) {
if (!model) {
this.replaceWith('/404');
return;
}
var self = this,
noSubcategories = params && !!params.no_subcategories,
filterMode = "category/" + Discourse.Category.slugFor(model) + (noSubcategories ? "/none" : "") + "/l/" + filter,
listFilter = "category/" + Discourse.Category.slugFor(model) + "/l/" + filter;
this.controllerFor('search').set('searchContext', model.get('searchContext'));
var opts = { category: model, filterMode: filterMode };
opts.noSubcategories = params && params.no_subcategories;
opts.canEditCategory = Discourse.User.currentProp('staff');
opts.canChangeCategoryNotificationLevel = Discourse.User.current();
this.controllerFor('navigation/category').setProperties(opts);
var queryParams = transaction.queryParams;
params = params || {};
if (queryParams && queryParams.order) { params.order = queryParams.order; }
if (queryParams && queryParams.ascending) { params.ascending = queryParams.ascending; }
if (queryParams && queryParams.status) { params.status = queryParams.status; }
return Discourse.TopicList.list(listFilter, params).then(function(list) {
var tracking = Discourse.TopicTrackingState.current();
if (tracking) {
tracking.sync(list, listFilter);
tracking.trackIncoming(listFilter);
}
// If all the categories are the same, we can hide them
var hideCategory = !list.get('topics').find(function (t) { return t.get('category') !== model; });
list.set('hideCategory', hideCategory);
self.set('topics', list);
});
},
setupController: function(controller, model) {
var topics = this.get('topics'),
period = filter.indexOf('/') > 0 ? filter.split('/')[1] : '',
filterText = I18n.t('filters.' + filter.replace('/', '.') + '.title', {count: 0});
Discourse.set('title', I18n.t('filters.with_category', { filter: filterText, category: model.get('name').capitalize() }));
this.controllerFor('navigation/category').set('canCreateTopic', topics.get('can_create_topic'));
this.controllerFor('discovery/topics').setProperties({
model: topics,
category: model,
period: period,
selected: [],
noSubcategories: params && !!params.no_subcategories
});
this.set('topics', null);
},
renderTemplate: function() {
this.render('navigation/category', { outlet: 'navigation-bar' });
this.render('discovery/topics', { controller: 'discovery/topics', outlet: 'list-container' });
},
deactivate: function() {
this._super();
this.controllerFor('search').set('searchContext', null);
},
actions: {
setNotification: function(notification_level){
this.currentModel.setNotification(notification_level);
}
}
});
}

View File

@ -0,0 +1,82 @@
// A helper to build a topic route for a filter
export default function(filter) {
return Discourse.Route.extend({
queryParams: {
sort: { replace: true },
ascending: { replace: true },
status: { replace: true }
},
beforeModel: function() {
this.controllerFor('navigation/default').set('filterMode', filter);
},
model: function(data, transaction) {
var params = transaction.queryParams;
// attempt to stop early cause we need this to be called before .sync
Discourse.ScreenTrack.current().stop();
var findOpts = {};
if (params && params.order) { findOpts.order = params.order; }
if (params && params.ascending) { findOpts.ascending = params.ascending; }
if (params && params.status) { findOpts.status = params.status; }
return Discourse.TopicList.list(filter, findOpts).then(function(list) {
var tracking = Discourse.TopicTrackingState.current();
if (tracking) {
tracking.sync(list, filter);
tracking.trackIncoming(filter);
}
return list;
});
},
setupController: function(controller, model, trans) {
controller.setProperties({
order: Em.get(trans, 'queryParams.order'),
ascending: Em.get(trans, 'queryParams.ascending')
});
var period = filter.indexOf('/') > 0 ? filter.split('/')[1] : '',
filterText = I18n.t('filters.' + filter.replace('/', '.') + '.title', {count: 0});
if (filter === Discourse.Utilities.defaultHomepage()) {
Discourse.set('title', '');
} else {
Discourse.set('title', I18n.t('filters.with_topics', {filter: filterText}));
}
this.controllerFor('discovery/topics').setProperties({
model: model,
category: null,
period: period,
selected: []
});
// If there's a draft, open the create topic composer
if (model.draft) {
var composer = this.controllerFor('composer');
if (!composer.get('model.viewOpen')) {
composer.open({
action: Discourse.Composer.CREATE_TOPIC,
draft: model.draft,
draftKey: model.draft_key,
draftSequence: model.draft_sequence
});
}
}
this.controllerFor('navigation/default').set('canCreateTopic', model.get('can_create_topic'));
},
renderTemplate: function() {
this.render('navigation/default', { outlet: 'navigation-bar' });
this.render('discovery/topics', { controller: 'discovery/topics', outlet: 'list-container' });
}
});
}

View File

@ -1,198 +0,0 @@
/**
A builder to create routes for topic discovery.
@function buildTopicRoute
@param {String} filter to create route for
**/
function buildTopicRoute(filter) {
return Discourse.Route.extend({
queryParams: {
sort: { replace: true },
ascending: { replace: true },
status: { replace: true }
},
beforeModel: function() {
this.controllerFor('navigation/default').set('filterMode', filter);
},
model: function(data, transaction) {
var params = transaction.queryParams;
// attempt to stop early cause we need this to be called before .sync
Discourse.ScreenTrack.current().stop();
var findOpts = {};
if (params && params.order) { findOpts.order = params.order; }
if (params && params.ascending) { findOpts.ascending = params.ascending; }
if (params && params.status) { findOpts.status = params.status; }
return Discourse.TopicList.list(filter, findOpts).then(function(list) {
var tracking = Discourse.TopicTrackingState.current();
if (tracking) {
tracking.sync(list, filter);
tracking.trackIncoming(filter);
}
return list;
});
},
setupController: function(controller, model, trans) {
controller.setProperties({
order: Em.get(trans, 'queryParams.order'),
ascending: Em.get(trans, 'queryParams.ascending')
});
var period = filter.indexOf('/') > 0 ? filter.split('/')[1] : '',
filterText = I18n.t('filters.' + filter.replace('/', '.') + '.title', {count: 0});
if (filter === Discourse.Utilities.defaultHomepage()) {
Discourse.set('title', '');
} else {
Discourse.set('title', I18n.t('filters.with_topics', {filter: filterText}));
}
this.controllerFor('discovery/topics').setProperties({
model: model,
category: null,
period: period,
selected: []
});
// If there's a draft, open the create topic composer
if (model.draft) {
var composer = this.controllerFor('composer');
if (!composer.get('model.viewOpen')) {
composer.open({
action: Discourse.Composer.CREATE_TOPIC,
draft: model.draft,
draftKey: model.draft_key,
draftSequence: model.draft_sequence
});
}
}
this.controllerFor('navigation/default').set('canCreateTopic', model.get('can_create_topic'));
},
renderTemplate: function() {
this.render('navigation/default', { outlet: 'navigation-bar' });
this.render('discovery/topics', { controller: 'discovery/topics', outlet: 'list-container' });
}
});
}
/**
A builder to create routes for topic discovery within a category.
@function buildTopicRoute
@param {String} filter to create route for
@param {Object} params with additional options
**/
function buildCategoryRoute(filter, params) {
return Discourse.Route.extend({
model: function(params) {
return Discourse.Category.findBySlug(params.slug, params.parentSlug);
},
afterModel: function(model, transaction) {
if (!model) {
this.replaceWith('/404');
return;
}
var self = this,
noSubcategories = params && !!params.no_subcategories,
filterMode = "category/" + Discourse.Category.slugFor(model) + (noSubcategories ? "/none" : "") + "/l/" + filter,
listFilter = "category/" + Discourse.Category.slugFor(model) + "/l/" + filter;
this.controllerFor('search').set('searchContext', model.get('searchContext'));
var opts = { category: model, filterMode: filterMode };
opts.noSubcategories = params && params.no_subcategories;
opts.canEditCategory = Discourse.User.currentProp('staff');
opts.canChangeCategoryNotificationLevel = Discourse.User.current();
this.controllerFor('navigation/category').setProperties(opts);
var queryParams = transaction.queryParams;
params = params || {};
if (queryParams && queryParams.order) { params.order = queryParams.order; }
if (queryParams && queryParams.ascending) { params.ascending = queryParams.ascending; }
if (queryParams && queryParams.status) { params.status = queryParams.status; }
return Discourse.TopicList.list(listFilter, params).then(function(list) {
var tracking = Discourse.TopicTrackingState.current();
if (tracking) {
tracking.sync(list, listFilter);
tracking.trackIncoming(listFilter);
}
// If all the categories are the same, we can hide them
var hideCategory = !list.get('topics').find(function (t) { return t.get('category') !== model; });
list.set('hideCategory', hideCategory);
self.set('topics', list);
});
},
setupController: function(controller, model) {
var topics = this.get('topics'),
period = filter.indexOf('/') > 0 ? filter.split('/')[1] : '',
filterText = I18n.t('filters.' + filter.replace('/', '.') + '.title', {count: 0});
Discourse.set('title', I18n.t('filters.with_category', { filter: filterText, category: model.get('name').capitalize() }));
this.controllerFor('navigation/category').set('canCreateTopic', topics.get('can_create_topic'));
this.controllerFor('discovery/topics').setProperties({
model: topics,
category: model,
period: period,
selected: [],
noSubcategories: params && !!params.no_subcategories
});
this.set('topics', null);
},
renderTemplate: function() {
this.render('navigation/category', { outlet: 'navigation-bar' });
this.render('discovery/topics', { controller: 'discovery/topics', outlet: 'list-container' });
},
deactivate: function() {
this._super();
this.controllerFor('search').set('searchContext', null);
},
actions: {
setNotification: function(notification_level){
this.currentModel.setNotification(notification_level);
}
}
});
}
// Finally, build all the routes with the helpers we created
Discourse.addInitializer(function() {
Discourse.DiscoveryCategoryRoute = buildCategoryRoute('latest');
Discourse.DiscoveryParentCategoryRoute = buildCategoryRoute('latest');
Discourse.DiscoveryCategoryNoneRoute = buildCategoryRoute('latest', {no_subcategories: true});
Discourse.Site.currentProp('filters').forEach(function(filter) {
Discourse["Discovery" + filter.capitalize() + "Controller"] = Discourse.DiscoverySortableController.extend();
Discourse["Discovery" + filter.capitalize() + "Route"] = buildTopicRoute(filter);
Discourse["Discovery" + filter.capitalize() + "CategoryRoute"] = buildCategoryRoute(filter);
Discourse["Discovery" + filter.capitalize() + "CategoryNoneRoute"] = buildCategoryRoute(filter, {no_subcategories: true});
});
Discourse.Site.currentProp('periods').forEach(function(period) {
Discourse["DiscoveryTop" + period.capitalize() + "Controller"] = Discourse.DiscoverySortableController.extend();
Discourse["DiscoveryTop" + period.capitalize() + "Route"] = buildTopicRoute('top/' + period);
Discourse["DiscoveryTop" + period.capitalize() + "CategoryRoute"] = buildCategoryRoute('top/' + period);
Discourse["DiscoveryTop" + period.capitalize() + "CategoryNoneRoute"] = buildCategoryRoute('top/' + period, {no_subcategories: true});
});
}, true);