1
0
mirror of https://github.com/flarum/core.git synced 2025-10-13 07:54:25 +02:00

Load discussion and posts with one request

Speeds things up a heap.
Also fix a whole bunch of bugs with the post stream.
This commit is contained in:
Toby Zerner
2015-02-06 10:30:38 +10:30
parent bc3aa449e7
commit 0365ae6c71
13 changed files with 279 additions and 164 deletions

View File

@@ -1,13 +1,22 @@
import Ember from 'ember';
export default Ember.Route.extend({
import PostStream from '../models/post-stream';
export default Ember.Route.extend({
queryParams: {
start: {replace: true}
},
model: function(params) {
return this.store.find('discussion', params.id);
// Each time we view a discussion we want to reload its posts from
// scratch so that we have the most up-to-date data. Also, if we were
// to leave them in the store, the stream would try and render them
// which has the potential to be slow.
this.store.unloadAll('post');
return this.store.findQueryOne('discussion', params.id, {
include: 'posts',
near: params.start
});
},
resetController: function(controller) {
@@ -19,18 +28,42 @@ export default Ember.Route.extend({
controller.set('stream', null);
},
setupController: function(controller, model) {
controller.setup(model);
setupController: function(controller, discussion) {
controller.set('model', discussion);
// Tell the discussions controller that the discussions list should be
// displayed as a pane, hidden on the side of the screen. Also set the
// application back button's target as the discussions controller.
this.controllerFor('index').set('paned', true);
this.controllerFor('application').set('backButtonTarget', this.controllerFor('index'));
// Set up the post stream object. It needs to know about the discussion
// it's representing the posts for, and we also need to inject the Ember
// Data store.
var stream = PostStream.create({
discussion: discussion,
store: this.store
});
controller.set('stream', stream);
// Next, we need to make sure we have a list of the discussion's post
// IDs. If we don't already have this information, we'll need to
// reload the discussion model.
var promise = discussion.get('posts') ? Ember.RSVP.resolve(discussion) : this.model({
id: discussion.get('id'),
start: controller.get('start')
});
// When we know we have the post IDs, we can set up the post stream with
// them. Then we will tell the view that we have finished loading so that
// it can scroll down to the appropriate post.
promise.then(function(discussion) {
stream.setup(discussion.get('postIds'));
controller.store.push('discussion', {id: discussion.get('id'), posts: ''});
if (controller.get('model') === discussion) {
controller.set('loaded', true);
Ember.run.scheduleOnce('afterRender', function() {
controller.trigger('loaded');
});
}
});
},
actions: {
queryParamsDidChange: function(params) {
// If the ?start param has changed, we want to tell the view to
// tell the streamContent component to jump to this start point.
@@ -39,26 +72,25 @@ export default Ember.Route.extend({
// queryParamsDidChange is fired before the controller is reset.
// Thus, controller.loaded would still be true and the
// startWasChanged event would be triggered inappropriately.
var controller = this.get('controller'),
oldStart = parseInt(this.get('controller.start'));
var newStart = parseInt(params.start) || 1;
var controller = this.controllerFor('discussion');
var oldStart = parseInt(controller.get('start'));
Ember.run.next(function() {
if (! params.start || ! controller || ! controller.get('loaded') || parseInt(params.start) === oldStart) {
return;
if (controller.get('loaded') && newStart !== oldStart) {
controller.trigger('startWasChanged', newStart);
}
controller.trigger('startWasChanged', params.start);
});
},
willTransition: function() {
didTransition: function() {
// When we transition into a new discussion, we want to hide the
// discussions list pane. This means that when the user selects a
// different discussion within the pane, the pane will slide away.
this.controllerFor('index').set('paneShowing', false);
// We also minimize the composer.
this.controllerFor('index')
.set('paned', true)
.set('paneShowing', false);
this.controllerFor('composer').send('minimize');
},
didTransition: function() {
this.controllerFor('composer').send('minimize');
}
}
});