Convert Composer to use Store

- Uses store for `PostStream`, `TopicList` too
This commit is contained in:
Robin Ward
2015-04-08 14:44:44 -04:00
parent a83a19f6ce
commit d4a05825da
23 changed files with 507 additions and 393 deletions

View File

@@ -0,0 +1,39 @@
import RestAdapter from 'discourse/adapters/rest';
function finderFor(filter, params) {
return function() {
let url = Discourse.getURL("/") + filter + ".json";
if (params) {
const keys = Object.keys(params),
encoded = [];
keys.forEach(function(p) {
const value = params[p];
if (typeof value !== 'undefined') {
encoded.push(p + "=" + value);
}
});
if (encoded.length > 0) {
url += "?" + encoded.join('&');
}
}
return Discourse.ajax(url);
};
}
export default RestAdapter.extend({
find(store, type, findArgs) {
const filter = findArgs.filter;
const params = findArgs.params;
return PreloadStore.getAndRemove("topic_list_" + filter, finderFor(filter, params)).then(function(result) {
result.filter = filter;
result.params = params;
return result;
});
}
});

View File

@@ -413,7 +413,7 @@ export default DiscourseController.extend({
composerModel.set('topic', opts.topic);
}
} else {
composerModel = composerModel || Discourse.Composer.create({ store: this.store });
composerModel = composerModel || this.store.createRecord('composer');
composerModel.open(opts);
}

View File

@@ -48,7 +48,8 @@ var controllerOpts = {
// router and ember throws an error due to missing `handlerInfos`.
// Lesson learned: Don't call `loading` yourself.
this.set('controllers.discovery.loading', true);
Discourse.TopicList.find(filter).then(function(list) {
this.store.findFiltered('topicList', {filter}).then(function(list) {
Discourse.TopicList.hideUniformCategory(list, self.get('category'));
self.setProperties({ model: list });

View File

@@ -1,3 +1,7 @@
import RestModel from 'discourse/models/rest';
import Post from 'discourse/models/post';
import Topic from 'discourse/models/topic';
const CLOSED = 'closed',
SAVING = 'saving',
OPEN = 'open',
@@ -26,7 +30,7 @@ const CLOSED = 'closed',
categoryId: 'topic.category.id'
};
const Composer = Discourse.Model.extend({
const Composer = RestModel.extend({
archetypes: function() {
return this.site.get('archetypes');
@@ -420,7 +424,8 @@ const Composer = Discourse.Model.extend({
post.get('post_number') === 1 &&
this.get('topic.details.can_edit')) {
const topicProps = this.getProperties(Object.keys(_edit_topic_serializer));
promise = Discourse.Topic.update(this.get('topic'), topicProps);
promise = Topic.update(this.get('topic'), topicProps);
} else {
promise = Ember.RSVP.resolve();
}
@@ -468,7 +473,7 @@ const Composer = Discourse.Model.extend({
let addedToStream = false;
// Build the post object
const createdPost = Discourse.Post.create({
const createdPost = Post.create({
imageSizes: opts.imageSizes,
cooked: this.getCookedHtml(),
reply_count: 0,

View File

@@ -1,4 +1,6 @@
const PostStream = Ember.Object.extend({
import RestModel from 'discourse/models/rest';
const PostStream = RestModel.extend({
loading: Em.computed.or('loadingAbove', 'loadingBelow', 'loadingFilter', 'stagingPost'),
notLoading: Em.computed.not('loading'),
filteredPostsCount: Em.computed.alias("stream.length"),
@@ -420,8 +422,9 @@ const PostStream = Ember.Object.extend({
} else {
// need to insert into stream
const url = "/posts/" + postId;
const store = this.store;
Discourse.ajax(url).then(function(p){
const post = Discourse.Post.create(p);
const post = store.createRecord('post', p);
const stream = self.get("stream");
const posts = self.get("posts");
self.storePost(post);
@@ -461,9 +464,10 @@ const PostStream = Ember.Object.extend({
if(existing){
const url = "/posts/" + postId;
const store = this.store;
Discourse.ajax(url).then(
function(p){
self.storePost(Discourse.Post.create(p));
self.storePost(store.createRecord('post', p));
},
function(){
self.removePosts([existing]);
@@ -480,8 +484,9 @@ const PostStream = Ember.Object.extend({
if (existing && existing.updated_at !== updatedAt) {
const url = "/posts/" + postId;
const store = this.store;
Discourse.ajax(url).then(function(p){
self.storePost(Discourse.Post.create(p));
self.storePost(store.createRecord('post', p));
});
}
},
@@ -491,9 +496,10 @@ const PostStream = Ember.Object.extend({
const postStream = this,
url = "/posts/" + post.get('id') + "/reply-history.json?max_replies=" + Discourse.SiteSettings.max_reply_history;
const store = this.store;
return Discourse.ajax(url).then(function(result) {
return result.map(function (p) {
return postStream.storePost(Discourse.Post.create(p));
return postStream.storePost(store.createRecord('post', p));
});
}).then(function (replyHistory) {
post.set('replyHistory', replyHistory);
@@ -594,8 +600,9 @@ const PostStream = Ember.Object.extend({
this.set('gaps', null);
if (postStreamData) {
// Load posts if present
const store = this.store;
postStreamData.posts.forEach(function(p) {
postStream.appendPost(Discourse.Post.create(p));
postStream.appendPost(store.createRecord('post', p));
});
delete postStreamData.posts;
@@ -671,11 +678,12 @@ const PostStream = Ember.Object.extend({
data = { post_ids: postIds },
postStream = this;
const store = this.store;
return Discourse.ajax(url, {data: data}).then(function(result) {
const posts = Em.get(result, "post_stream.posts");
if (posts) {
posts.forEach(function (p) {
postStream.storePost(Discourse.Post.create(p));
postStream.storePost(store.createRecord('post', p));
});
}
});
@@ -751,6 +759,8 @@ PostStream.reopenClass({
url += "/" + opts.nearPost;
}
delete opts.nearPost;
delete opts.__type;
delete opts.store;
return PreloadStore.getAndRemove("topic_" + topicId, function() {
return Discourse.ajax(url + ".json", {data: opts});

View File

@@ -394,32 +394,29 @@ const Post = RestModel.extend({
throw e;
});
}
});
Post.reopenClass({
createActionSummary(result) {
if (result.actions_summary) {
munge(json) {
if (json.actions_summary) {
const lookup = Em.Object.create();
// this area should be optimized, it is creating way too many objects per post
result.actions_summary = result.actions_summary.map(function(a) {
a.post = result;
json.actions_summary = json.actions_summary.map(function(a) {
a.post = json;
a.actionType = Discourse.Site.current().postActionTypeById(a.id);
const actionSummary = Discourse.ActionSummary.create(a);
lookup[a.actionType.name_key] = actionSummary;
return actionSummary;
});
result.set('actionByName', lookup);
json.actionByName = lookup;
}
},
create(obj) {
const result = this._super.apply(this, arguments);
this.createActionSummary(result);
if (obj && obj.reply_to_user) {
result.set('reply_to_user', Discourse.User.create(obj.reply_to_user));
if (json && json.reply_to_user) {
json.reply_to_user = Discourse.User.create(json.reply_to_user);
}
return result;
return json;
},
updateBookmark(postId, bookmarked) {

View File

@@ -1,16 +1,18 @@
import Presence from 'discourse/mixins/presence';
export default Ember.Object.extend(Presence, {
const RestModel = Ember.Object.extend(Presence, {
update(attrs) {
const self = this,
type = this.get('__type');
const munge = this.__munge;
return this.store.update(type, this.get('id'), attrs).then(function(result) {
if (result && result[type]) {
Object.keys(result).forEach(function(k) {
attrs[k] = result[k];
});
}
self.setProperties(attrs);
self.setProperties(munge(attrs));
return result;
});
},
@@ -20,3 +22,25 @@ export default Ember.Object.extend(Presence, {
return this.store.destroyRecord(type, this);
}
});
RestModel.reopenClass({
// Overwrite and JSON will be passed through here before `create` and `update`
munge(json) {
return json;
},
create(args) {
args = args || {};
if (!args.store) {
const container = Discourse.__container__;
Ember.warn('Use `store.createRecord` to create records instead of `.create()`');
args.store = container.lookup('store:main');
}
args.__munge = this.munge;
return this._super(this.munge(args, args.store));
}
});
export default RestModel;

View File

@@ -1,7 +1,14 @@
import RestModel from 'discourse/models/rest';
import ResultSet from 'discourse/models/result-set';
const _identityMap = {};
let _identityMap;
// You should only call this if you're a test scaffold
function flushMap() {
_identityMap = {};
}
flushMap();
export default Ember.Object.extend({
pluralize(thing) {
@@ -16,6 +23,15 @@ export default Ember.Object.extend({
});
},
// Mostly for legacy, things like TopicList without ResultSets
findFiltered(type, findArgs) {
const adapter = this.container.lookup('adapter:' + type) || this.container.lookup('adapter:rest');
const self = this;
return adapter.find(this, type, findArgs).then(function(result) {
return self._build(type, result);
});
},
find(type, findArgs) {
const adapter = this.container.lookup('adapter:' + type) || this.container.lookup('adapter:rest');
const self = this;
@@ -60,7 +76,8 @@ export default Ember.Object.extend({
},
createRecord(type, attrs) {
return this._hydrate(type, attrs);
attrs = attrs || {};
return !!attrs.id ? this._hydrate(type, attrs) : this._build(type, attrs);
},
destroyRecord(type, record) {
@@ -81,6 +98,19 @@ export default Ember.Object.extend({
return ResultSet.create({ content, totalRows, loadMoreUrl, store: this, __type: type });
},
_build(type, obj) {
obj.store = this;
obj.__type = type;
const klass = this.container.lookupFactory('model:' + type) || RestModel;
const model = klass.create(obj);
if (obj.id) {
_identityMap[type][obj.id] = model;
}
return model;
},
_hydrate(type, obj) {
if (!obj) { throw "Can't hydrate " + type + " of `null`"; }
if (!obj.id) { throw "Can't hydrate " + type + " without an `id`"; }
@@ -88,18 +118,17 @@ export default Ember.Object.extend({
_identityMap[type] = _identityMap[type] || {};
const existing = _identityMap[type][obj.id];
if (existing === obj) { return existing; }
if (existing) {
delete obj.id;
existing.setProperties(obj);
const klass = this.container.lookupFactory('model:' + type) || RestModel;
existing.setProperties(klass.munge(obj));
return existing;
}
obj.store = this;
obj.__type = type;
const klass = this.container.lookupFactory('model:' + type) || RestModel;
const model = klass.create(obj);
_identityMap[type][obj.id] = model;
return model;
return this._build(type, obj);
}
});
export { flushMap };

View File

@@ -2,7 +2,9 @@
A model representing a Topic's details that aren't always present, such as a list of participants.
When showing topics in lists and such this information should not be required.
**/
const TopicDetails = Discourse.Model.extend({
import RestModel from 'discourse/models/rest';
const TopicDetails = RestModel.extend({
loaded: false,
updateFromJson(details) {
@@ -15,8 +17,9 @@ const TopicDetails = Discourse.Model.extend({
}
if (details.suggested_topics) {
const store = this.store;
details.suggested_topics = details.suggested_topics.map(function (st) {
return Discourse.Topic.create(st);
return store.createRecord('topic', st);
});
}

View File

@@ -0,0 +1,163 @@
import RestModel from 'discourse/models/rest';
import Model from 'discourse/models/model';
function topicsFrom(result, store) {
if (!result) { return; }
// Stitch together our side loaded data
const categories = Discourse.Category.list(),
users = Model.extractByKey(result.users, Discourse.User);
return result.topic_list.topics.map(function (t) {
t.category = categories.findBy('id', t.category_id);
t.posters.forEach(function(p) {
p.user = users[p.user_id];
});
if (t.participants) {
t.participants.forEach(function(p) {
p.user = users[p.user_id];
});
}
return store.createRecord('topic', t);
});
}
const TopicList = RestModel.extend({
canLoadMore: Em.computed.notEmpty("more_topics_url"),
forEachNew: function(topics, callback) {
const topicIds = [];
_.each(this.get('topics'),function(topic) {
topicIds[topic.get('id')] = true;
});
_.each(topics,function(topic) {
if(!topicIds[topic.id]) {
callback(topic);
}
});
},
refreshSort: function(order, ascending) {
const self = this,
params = this.get('params');
params.order = order || params.order;
if (ascending === undefined) {
params.ascending = ascending;
} else {
params.ascending = ascending;
}
this.set('loaded', false);
const store = this.store;
store.findFiltered('topicList', {filter: this.get('filter'), params}).then(function(tl) {
const newTopics = tl.get('topics'),
topics = self.get('topics');
topics.clear();
topics.pushObjects(newTopics);
self.setProperties({ loaded: true, more_topics_url: newTopics.get('more_topics_url') });
});
},
loadMore: function() {
if (this.get('loadingMore')) { return Ember.RSVP.resolve(); }
const moreUrl = this.get('more_topics_url');
if (moreUrl) {
const self = this;
this.set('loadingMore', true);
const store = this.store;
return Discourse.ajax({url: moreUrl}).then(function (result) {
let topicsAdded = 0;
if (result) {
// the new topics loaded from the server
const newTopics = topicsFrom(result, store),
topics = self.get("topics");
self.forEachNew(newTopics, function(t) {
t.set('highlight', topicsAdded++ === 0);
topics.pushObject(t);
});
self.setProperties({
loadingMore: false,
more_topics_url: result.topic_list.more_topics_url
});
Discourse.Session.currentProp('topicList', self);
return self.get('more_topics_url');
}
});
} else {
// Return a promise indicating no more results
return Ember.RSVP.resolve();
}
},
// loads topics with these ids "before" the current topics
loadBefore: function(topic_ids){
const topicList = this,
topics = this.get('topics');
// refresh dupes
topics.removeObjects(topics.filter(function(topic){
return topic_ids.indexOf(topic.get('id')) >= 0;
}));
const url = Discourse.getURL("/") + this.get('filter') + "?topic_ids=" + topic_ids.join(",");
const store = this.store;
return Discourse.ajax({ url }).then(function(result) {
let i = 0;
topicList.forEachNew(topicsFrom(result, store), function(t) {
// highlight the first of the new topics so we can get a visual feedback
t.set('highlight', true);
topics.insertAt(i,t);
i++;
});
Discourse.Session.currentProp('topicList', topicList);
});
}
});
TopicList.reopenClass({
munge(json, store) {
json.inserted = json.inserted || [];
json.can_create_topic = json.topic_list.can_create_topic;
json.more_topics_url = json.topic_list.more_topics_url;
json.draft_key = json.topic_list.draft_key;
json.draft_sequence = json.topic_list.draft_sequence;
json.draft = json.topic_list.draft;
json.for_period = json.topic_list.for_period;
json.loaded = true;
json.per_page = json.topic_list.per_page;
json.topics = topicsFrom(json, store);
if (json.topic_list.filtered_category) {
json.category = Discourse.Category.create(json.topic_list.filtered_category);
}
return json;
},
find(filter, params) {
const store = Discourse.__container__.lookup('store:main');
return store.findFiltered('topicList', {filter, params});
},
// Sets `hideCategory` if all topics in the last have a particular category
hideUniformCategory(list, category) {
const hideCategory = !list.get('topics').any(function (t) { return t.get('category') !== category; });
list.set('hideCategory', hideCategory);
}
});
export default TopicList;

View File

@@ -1,7 +1,6 @@
import TopicDetails from 'discourse/models/topic-details';
import PostStream from 'discourse/models/post-stream';
import RestModel from 'discourse/models/rest';
const Topic = Discourse.Model.extend({
const Topic = RestModel.extend({
// returns createdAt if there's no bumped date
bumpedAt: function() {
@@ -23,7 +22,7 @@ const Topic = Discourse.Model.extend({
}.property('created_at'),
postStream: function() {
return PostStream.create({topic: this});
return this.store.createRecord('postStream', {id: this.get('id'), topic: this});
}.property(),
replyCount: function() {
@@ -31,7 +30,7 @@ const Topic = Discourse.Model.extend({
}.property('posts_count'),
details: function() {
return TopicDetails.create({topic: this});
return this.store.createRecord('topicDetails', {id: this.get('id'), topic: this});
}.property(),
invisible: Em.computed.not('visible'),

View File

@@ -1,272 +0,0 @@
function finderFor(filter, params) {
return function() {
var url = Discourse.getURL("/") + filter + ".json";
if (params) {
var keys = Object.keys(params),
encoded = [];
keys.forEach(function(p) {
var value = params[p];
if (typeof value !== 'undefined') {
encoded.push(p + "=" + value);
}
});
if (encoded.length > 0) {
url += "?" + encoded.join('&');
}
}
return Discourse.ajax(url);
};
}
Discourse.TopicList = Discourse.Model.extend({
canLoadMore: Em.computed.notEmpty("more_topics_url"),
forEachNew: function(topics, callback) {
var topicIds = [];
_.each(this.get('topics'),function(topic) {
topicIds[topic.get('id')] = true;
});
_.each(topics,function(topic) {
if(!topicIds[topic.id]) {
callback(topic);
}
});
},
refreshSort: function(order, ascending) {
var self = this,
params = this.get('params');
params.order = order || params.order;
if (ascending === undefined) {
params.ascending = ascending;
} else {
params.ascending = ascending;
}
this.set('loaded', false);
var finder = finderFor(this.get('filter'), params);
finder().then(function (result) {
var newTopics = Discourse.TopicList.topicsFrom(result),
topics = self.get('topics');
topics.clear();
topics.pushObjects(newTopics);
self.setProperties({ loaded: true, more_topics_url: result.topic_list.more_topics_url });
});
},
loadMore: function() {
if (this.get('loadingMore')) { return Ember.RSVP.resolve(); }
var moreUrl = this.get('more_topics_url');
if (moreUrl) {
var self = this;
this.set('loadingMore', true);
return Discourse.ajax({url: moreUrl}).then(function (result) {
var topicsAdded = 0;
if (result) {
// the new topics loaded from the server
var newTopics = Discourse.TopicList.topicsFrom(result),
topics = self.get("topics");
self.forEachNew(newTopics, function(t) {
t.set('highlight', topicsAdded++ === 0);
topics.pushObject(t);
});
self.setProperties({
loadingMore: false,
more_topics_url: result.topic_list.more_topics_url
});
Discourse.Session.currentProp('topicList', self);
return self.get('more_topics_url');
}
});
} else {
// Return a promise indicating no more results
return Ember.RSVP.resolve();
}
},
// loads topics with these ids "before" the current topics
loadBefore: function(topic_ids){
var topicList = this,
topics = this.get('topics');
// refresh dupes
topics.removeObjects(topics.filter(function(topic){
return topic_ids.indexOf(topic.get('id')) >= 0;
}));
Discourse.TopicList.loadTopics(topic_ids, this.get('filter'))
.then(function(newTopics){
var i = 0;
topicList.forEachNew(newTopics, function(t) {
// highlight the first of the new topics so we can get a visual feedback
t.set('highlight', true);
topics.insertAt(i,t);
i++;
});
Discourse.Session.currentProp('topicList', topicList);
});
}
});
Discourse.TopicList.reopenClass({
loadTopics: function(topic_ids, filter) {
return new Ember.RSVP.Promise(function(resolve, reject) {
var url = Discourse.getURL("/") + filter + "?topic_ids=" + topic_ids.join(",");
Discourse.ajax({url: url}).then(function (result) {
if (result) {
// the new topics loaded from the server
var newTopics = Discourse.TopicList.topicsFrom(result);
resolve(newTopics);
} else {
reject();
}
}).catch(reject);
});
},
/**
Stitch together side loaded topic data
@method topicsFrom
@param {Object} result JSON object with topic data
@returns {Array} the list of topics
**/
topicsFrom: function(result) {
// Stitch together our side loaded data
var categories = Discourse.Category.list(),
users = this.extractByKey(result.users, Discourse.User);
return result.topic_list.topics.map(function (t) {
t.category = categories.findBy('id', t.category_id);
t.posters.forEach(function(p) {
p.user = users[p.user_id];
});
if (t.participants) {
t.participants.forEach(function(p) {
p.user = users[p.user_id];
});
}
return Discourse.Topic.create(t);
});
},
from: function(result, filter, params) {
var topicList = Discourse.TopicList.create({
inserted: [],
filter: filter,
params: params || {},
topics: Discourse.TopicList.topicsFrom(result),
can_create_topic: result.topic_list.can_create_topic,
more_topics_url: result.topic_list.more_topics_url,
draft_key: result.topic_list.draft_key,
draft_sequence: result.topic_list.draft_sequence,
draft: result.topic_list.draft,
for_period: result.topic_list.for_period,
loaded: true,
per_page: result.topic_list.per_page
});
if (result.topic_list.filtered_category) {
topicList.set('category', Discourse.Category.create(result.topic_list.filtered_category));
}
return topicList;
},
/**
Lists topics on a given menu item
@method list
@param {Object} filter The menu item to filter to
@param {Object} params Any additional params to pass to TopicList.find()
@param {Object} extras Additional finding options, such as caching
@returns {Promise} a promise that resolves to the list of topics
**/
list: function(filter, filterParams, extras) {
var tracking = Discourse.TopicTrackingState.current();
extras = extras || {};
return new Ember.RSVP.Promise(function(resolve) {
var session = Discourse.Session.current();
if (extras.cached) {
var cachedList = session.get('topicList');
// Try to use the cached version if it exists and is greater than the topics per page
if (cachedList && (cachedList.get('filter') === filter) &&
(cachedList.get('topics.length') || 0) > cachedList.get('per_page') &&
_.isEqual(cachedList.get('listParams'), filterParams)) {
cachedList.set('loaded', true);
if (tracking) {
tracking.updateTopics(cachedList.get('topics'));
}
return resolve(cachedList);
}
session.set('topicList', null);
} else {
// Clear the cache
session.setProperties({topicList: null, topicListScrollPosition: null});
}
// Clean up any string parameters that might slip through
filterParams = filterParams || {};
Ember.keys(filterParams).forEach(function(k) {
var val = filterParams[k];
if (val === "undefined" || val === "null" || val === 'false') {
filterParams[k] = undefined;
}
});
var findParams = {};
Discourse.SiteSettings.top_menu.split('|').forEach(function (i) {
if (i.indexOf(filter) === 0) {
var exclude = i.split("-");
if (exclude && exclude.length === 2) {
findParams.exclude_category = exclude[1];
}
}
});
return resolve(Discourse.TopicList.find(filter, _.extend(findParams, filterParams || {})));
}).then(function(list) {
list.set('listParams', filterParams);
if (tracking) {
tracking.sync(list, list.filter);
tracking.trackIncoming(list.filter);
}
Discourse.Session.currentProp('topicList', list);
return list;
});
},
find: function(filter, params) {
return PreloadStore.getAndRemove("topic_list_" + filter, finderFor(filter, params)).then(function(result) {
return Discourse.TopicList.from(result, filter, params);
});
},
// Sets `hideCategory` if all topics in the last have a particular category
hideUniformCategory: function(list, category) {
var hideCategory = !list.get('topics').any(function (t) { return t.get('category') !== category; });
list.set('hideCategory', hideCategory);
}
});

View File

@@ -1,4 +1,4 @@
import { queryParams, filterQueryParams } from 'discourse/routes/build-topic-route';
import { queryParams, filterQueryParams, findTopicList } from 'discourse/routes/build-topic-route';
// A helper function to create a category route with parameters
export default function(filter, params) {
@@ -52,7 +52,7 @@ export default function(filter, params) {
var findOpts = filterQueryParams(transition.queryParams, params),
extras = { cached: this.isPoppedState(transition) };
return Discourse.TopicList.list(listFilter, findOpts, extras).then(function(list) {
return findTopicList(this.store, listFilter, findOpts, extras).then(function(list) {
Discourse.TopicList.hideUniformCategory(list, model);
self.set('topics', list);
});

View File

@@ -11,6 +11,65 @@ function filterQueryParams(params, defaultParams) {
return findOpts;
}
function findTopicList(store, filter, filterParams, extras) {
const tracking = Discourse.TopicTrackingState.current();
extras = extras || {};
return new Ember.RSVP.Promise(function(resolve) {
const session = Discourse.Session.current();
if (extras.cached) {
const cachedList = session.get('topicList');
// Try to use the cached version if it exists and is greater than the topics per page
if (cachedList && (cachedList.get('filter') === filter) &&
(cachedList.get('topics.length') || 0) > cachedList.get('per_page') &&
_.isEqual(cachedList.get('listParams'), filterParams)) {
cachedList.set('loaded', true);
if (tracking) {
tracking.updateTopics(cachedList.get('topics'));
}
return resolve(cachedList);
}
session.set('topicList', null);
} else {
// Clear the cache
session.setProperties({topicList: null, topicListScrollPosition: null});
}
// Clean up any string parameters that might slip through
filterParams = filterParams || {};
Ember.keys(filterParams).forEach(function(k) {
const val = filterParams[k];
if (val === "undefined" || val === "null" || val === 'false') {
filterParams[k] = undefined;
}
});
const findParams = {};
Discourse.SiteSettings.top_menu.split('|').forEach(function (i) {
if (i.indexOf(filter) === 0) {
const exclude = i.split("-");
if (exclude && exclude.length === 2) {
findParams.exclude_category = exclude[1];
}
}
});
return resolve(store.findFiltered('topicList', { filter, params:_.extend(findParams, filterParams || {})}));
}).then(function(list) {
list.set('listParams', filterParams);
if (tracking) {
tracking.sync(list, list.filter);
tracking.trackIncoming(list.filter);
}
Discourse.Session.currentProp('topicList', list);
return list;
});
}
export default function(filter, extras) {
extras = extras || {};
return Discourse.Route.extend({
@@ -28,7 +87,7 @@ export default function(filter, extras) {
const findOpts = filterQueryParams(transition.queryParams),
extras = { cached: this.isPoppedState(transition) };
return Discourse.TopicList.list(filter, findOpts, extras);
return findTopicList(this.store, filter, findOpts, extras);
},
titleToken() {
@@ -72,4 +131,4 @@ export default function(filter, extras) {
}, extras);
}
export { filterQueryParams };
export { filterQueryParams, findTopicList };

View File

@@ -14,7 +14,7 @@ export default function (viewName, path) {
},
model: function() {
return Discourse.TopicList.find('topics/' + path + '/' + this.modelFor('user').get('username_lower'));
return this.store.findFiltered('topicList', {filter: 'topics/' + path + '/' + this.modelFor('user').get('username_lower')});
},
setupController: function() {

View File

@@ -5,7 +5,6 @@ let isTransitioning = false,
const SCROLL_DELAY = 500;
import ShowFooter from "discourse/mixins/show-footer";
import Topic from 'discourse/models/topic';
import showModal from 'discourse/lib/show-modal';
const TopicRoute = Discourse.Route.extend(ShowFooter, {
@@ -153,7 +152,7 @@ const TopicRoute = Discourse.Route.extend(ShowFooter, {
model(params, transition) {
const queryParams = transition.queryParams;
const topic = this.modelFor('topic');
let topic = this.modelFor('topic');
if (topic && (topic.get('id') === parseInt(params.id, 10))) {
this.setupParams(topic, queryParams);
// If we have the existing model, refresh it
@@ -161,7 +160,8 @@ const TopicRoute = Discourse.Route.extend(ShowFooter, {
return topic;
});
} else {
return this.setupParams(Topic.create(_.omit(params, 'username_filters', 'filter')), queryParams);
topic = this.store.createRecord('topic', _.omit(params, 'username_filters', 'filter'));
return this.setupParams(topic, queryParams);
}
},

View File

@@ -4,6 +4,6 @@ export default UserTopicListRoute.extend({
userActionType: Discourse.UserAction.TYPES.topics,
model: function() {
return Discourse.TopicList.find('topics/created-by/' + this.modelFor('user').get('username_lower'));
return this.store.findFiltered('topicList', {filter: 'topics/created-by/' + this.modelFor('user').get('username_lower') });
}
});

View File

@@ -27,11 +27,11 @@
//= require ./discourse/models/rest
//= require ./discourse/models/model
//= require ./discourse/models/post
//= require ./discourse/models/user_action
//= require ./discourse/models/composer
//= require ./discourse/models/post-stream
//= require ./discourse/models/topic-details
//= require ./discourse/models/topic
//= require ./discourse/models/user_action
//= require ./discourse/models/composer
//= require ./discourse/controllers/controller
//= require ./discourse/controllers/discovery-sortable
//= require ./discourse/controllers/object