mirror of
https://github.com/flarum/framework.git
synced 2024-12-15 08:33:38 +08:00
011ae3603e
Record when the discussion was renamed, from what, and by whom. Information is stored in the `content` field as a serialised JSON object because proper polymorphism will be too difficult with Ember Data and especially when extensions try to add new post types.
126 lines
5.0 KiB
JavaScript
126 lines
5.0 KiB
JavaScript
import Ember from 'ember';
|
|
|
|
import PostStream from 'flarum/models/post-stream';
|
|
|
|
export default Ember.Route.extend({
|
|
queryParams: {
|
|
start: {replace: true}
|
|
},
|
|
|
|
discussion: function(id, start) {
|
|
return this.store.findQueryOne('discussion', id, {
|
|
include: 'posts',
|
|
near: start
|
|
});
|
|
},
|
|
|
|
// When we fetch the discussion from the model hook (i.e. on a fresh page
|
|
// load), we'll wrap it in an object proxy and set a `loaded` flag to true
|
|
// so that it won't be reloaded later on.
|
|
model: function(params) {
|
|
return this.discussion(params.id, params.start).then(function(discussion) {
|
|
return Ember.ObjectProxy.create({content: discussion, loaded: true});
|
|
});
|
|
},
|
|
|
|
resetController: function(controller) {
|
|
// Whenever we exit the discussion view, or transition to a different
|
|
// discussion, we want to reset the query params so that they don't stick.
|
|
controller.set('start', '1');
|
|
controller.set('searchQuery', '');
|
|
controller.set('loaded', false);
|
|
controller.set('stream', null);
|
|
},
|
|
|
|
setupController: function(controller, discussion) {
|
|
controller.set('model', discussion);
|
|
this.controllerFor('index/index').set('lastDiscussion', discussion);
|
|
|
|
// 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);
|
|
|
|
// We need to make sure we have an up-to-date list of the discussion's
|
|
// post IDs. If we didn't enter this route using the model hook (like if
|
|
// clicking on a discussion in the index), then we'll reload the model.
|
|
var promise = discussion.get('loaded') ?
|
|
Ember.RSVP.resolve(discussion.get('content')) :
|
|
this.discussion(discussion.get('id'), 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) {
|
|
controller.set('model', discussion);
|
|
var postIds = discussion.get('postIds');
|
|
stream.setup(postIds);
|
|
|
|
// A page of posts will have been returned as linked data by this
|
|
// request, and automatically loaded into the store. In turn, we
|
|
// want to load them into the stream. However, since there is no
|
|
// way to access them directly, we need to retrieve them based on
|
|
// the requested start number. This code finds the post for that
|
|
// number, gets its index, slices an array of surrounding post
|
|
// IDs, and finally adds these posts to the stream.
|
|
var posts = discussion.get('loadedPosts');
|
|
var startPost = posts.findBy('number', parseInt(controller.get('start')));
|
|
if (startPost) {
|
|
var startIndex = postIds.indexOf(startPost.get('id'));
|
|
var count = stream.get('postLoadCount');
|
|
startIndex = Math.max(0, startIndex - count / 2);
|
|
var loadIds = postIds.slice(startIndex, startIndex + count);
|
|
stream.addPosts(posts.filter(function(item) {
|
|
return loadIds.indexOf(item.get('id')) !== -1;
|
|
}));
|
|
}
|
|
|
|
// It's possible for this promise to have resolved but the user
|
|
// has clicked away to a different discussion. So only if we're
|
|
// still on the original one, we will tell the view that we're
|
|
// done loading.
|
|
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.
|
|
// We postpone running this code until the next run loop because
|
|
// when transitioning directly from one discussion to another,
|
|
// queryParamsDidChange is fired before the controller is reset.
|
|
// Thus, controller.loaded would still be true and the
|
|
// startWasChanged event would be triggered inappropriately.
|
|
var newStart = parseInt(params.start) || 1;
|
|
var controller = this.controllerFor('discussion');
|
|
var oldStart = parseInt(controller.get('start'));
|
|
Ember.run.next(function() {
|
|
if (controller.get('loaded') && newStart !== oldStart) {
|
|
controller.trigger('startWasChanged', newStart);
|
|
}
|
|
});
|
|
},
|
|
|
|
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.
|
|
// We also minimize the composer.
|
|
this.controllerFor('index')
|
|
.set('paned', true)
|
|
.set('paneShowing', false);
|
|
this.controllerFor('composer').send('minimize');
|
|
}
|
|
}
|
|
});
|