diff --git a/app/assets/javascripts/discourse/lib/posts-with-placeholders.js.es6 b/app/assets/javascripts/discourse/lib/posts-with-placeholders.js.es6 new file mode 100644 index 00000000000..db7f1238a72 --- /dev/null +++ b/app/assets/javascripts/discourse/lib/posts-with-placeholders.js.es6 @@ -0,0 +1,59 @@ +import { Placeholder } from 'discourse/views/cloaked'; +import { default as computed } from 'ember-addons/ember-computed-decorators'; + + +export default Ember.Object.extend(Ember.Array, { + posts: null, + _appendingIds: null, + + init() { + this._appendingIds = {}; + }, + + @computed + length() { + return this.get('posts.length') + Object.keys(this._appendingIds || {}).length; + }, + + _changeArray(cb, offset, removed, inserted) { + this.arrayContentWillChange(offset, removed, inserted); + cb(); + this.arrayContentDidChange(offset, removed, inserted); + this.propertyDidChange('length'); + }, + + clear(cb) { + this._changeArray(cb, 0, this.get('posts.length'), 0); + }, + + appendPost(cb) { + this._changeArray(cb, this.get('posts.length'), 0, 1); + }, + + removePost(cb) { + this._changeArray(cb, this.get('posts.length') - 1, 1, 0); + }, + + appending(postIds) { + this._changeArray(() => { + const appendingIds = this._appendingIds; + postIds.forEach(pid => appendingIds[pid] = true); + }, this.get('length'), 0, postIds.length); + }, + + finishedAppending(postIds) { + this._changeArray(() => { + const appendingIds = this._appendingIds; + postIds.forEach(pid => delete appendingIds[pid]); + }, this.get('posts.length') - postIds.length, postIds.length, postIds.length); + }, + + finishedPrepending(postIds) { + this._changeArray(Ember.K, 0, 0, postIds.length); + }, + + objectAt(index) { + const posts = this.get('posts'); + return (index < posts.length) ? posts[index] : new Placeholder('post-placeholder'); + }, +}); diff --git a/app/assets/javascripts/discourse/models/post-stream.js.es6 b/app/assets/javascripts/discourse/models/post-stream.js.es6 index d74227d18fe..58640051864 100644 --- a/app/assets/javascripts/discourse/models/post-stream.js.es6 +++ b/app/assets/javascripts/discourse/models/post-stream.js.es6 @@ -1,7 +1,8 @@ import DiscourseURL from 'discourse/lib/url'; import RestModel from 'discourse/models/rest'; +import PostsWithPlaceholders from 'discourse/lib/posts-with-placeholders'; import { default as computed } from 'ember-addons/ember-computed-decorators'; -import { Placeholder } from 'discourse/views/cloaked'; +import { loadTopicView } from 'discourse/models/topic'; function calcDayDiff(p1, p2) { if (!p1) { return; } @@ -18,94 +19,6 @@ function calcDayDiff(p1, p2) { } } -export function loadTopicView(topic, args) { - const topicId = topic.get('id'); - const data = _.merge({}, args); - const url = Discourse.getURL("/t/") + topicId; - const jsonUrl = (data.nearPost ? `${url}/${data.nearPost}` : url) + '.json'; - - delete data.nearPost; - delete data.__type; - delete data.store; - - return PreloadStore.getAndRemove(`topic_${topicId}`, () => { - return Discourse.ajax(jsonUrl, {data}); - }).then(json => { - topic.updateFromJson(json); - return json; - }); -} - -const PostsWithPlaceholders = Ember.Object.extend(Ember.Array, { - posts: null, - _appendingIds: null, - - init() { - this._appendingIds = {}; - }, - - @computed - length() { - return this.get('posts.length') + Object.keys(this._appendingIds || {}).length; - }, - - clear(cb) { - const l = this.get('posts.length'); - this.arrayContentWillChange(0, l, 0); - cb(); - this.arrayContentWillChange(0, l, 0); - this.propertyDidChange('length'); - }, - - append(cb) { - const l = this.get('posts.length'); - this.arrayContentWillChange(l, 0, 1); - cb(); - this.arrayContentDidChange(l, 0, 1); - this.propertyDidChange('length'); - }, - - removePost(cb) { - const l = this.get('posts.length') - 1; - this.arrayContentWillChange(l, 1, 0); - cb(); - this.arrayContentDidChange(l, 1, 0); - this.propertyDidChange('length'); - }, - - appending(postIds) { - const l = this.get('length'); - this.arrayContentWillChange(l, 0, postIds.length); - const appendingIds = this._appendingIds; - postIds.forEach(pid => appendingIds[pid] = true); - this.arrayContentDidChange(l, 0, postIds.length); - this.propertyDidChange('length'); - }, - - finishedAppending(postIds) { - const l = this.get('posts.length') - postIds.length; - this.arrayContentWillChange(l, postIds.length, postIds.length); - const appendingIds = this._appendingIds; - postIds.forEach(pid => delete appendingIds[pid]); - this.arrayContentDidChange(l, postIds.length, postIds.length); - this.propertyDidChange('length'); - }, - - finishedPrepending(postIds) { - this.arrayContentDidChange(0, 0, postIds.length); - this.propertyDidChange('length'); - }, - - objectAt(index) { - const posts = this.get('posts'); - if (index < posts.length) { - return posts[index]; - } else { - return new Placeholder('post-placeholder'); - } - }, -}); - export default RestModel.extend({ _identityMap: null, posts: null, @@ -517,7 +430,7 @@ export default RestModel.extend({ calcDayDiff(stored, this.get('lastAppended')); if (!posts.contains(stored)) { if (!this.get('loadingBelow')) { - this.get('postsWithPlaceholders').append(() => posts.pushObject(stored)); + this.get('postsWithPlaceholders').appendPost(() => posts.pushObject(stored)); } else { posts.pushObject(stored); } @@ -812,10 +725,8 @@ export default RestModel.extend({ return this.get('stream').indexOf(post.get('id')); }, - /** - Handles an error loading a topic based on a HTTP status code. Updates - the text to the correct values. - **/ + // Handles an error loading a topic based on a HTTP status code. Updates + // the text to the correct values. errorLoading(result) { const status = result.jqXHR.status; @@ -843,5 +754,4 @@ export default RestModel.extend({ // Otherwise supply a generic error message topic.set('message', I18n.t('topic.server_error.description')); } - }); diff --git a/app/assets/javascripts/discourse/models/topic.js.es6 b/app/assets/javascripts/discourse/models/topic.js.es6 index 889349f1db1..cd83dd9fb64 100644 --- a/app/assets/javascripts/discourse/models/topic.js.es6 +++ b/app/assets/javascripts/discourse/models/topic.js.es6 @@ -5,6 +5,24 @@ import { longDate } from 'discourse/lib/formatter'; import computed from 'ember-addons/ember-computed-decorators'; import ActionSummary from 'discourse/models/action-summary'; +export function loadTopicView(topic, args) { + const topicId = topic.get('id'); + const data = _.merge({}, args); + const url = Discourse.getURL("/t/") + topicId; + const jsonUrl = (data.nearPost ? `${url}/${data.nearPost}` : url) + '.json'; + + delete data.nearPost; + delete data.__type; + delete data.store; + + return PreloadStore.getAndRemove(`topic_${topicId}`, () => { + return Discourse.ajax(jsonUrl, {data}); + }).then(json => { + topic.updateFromJson(json); + return json; + }); +} + const Topic = RestModel.extend({ message: null, errorLoading: false, diff --git a/app/assets/javascripts/discourse/routes/topic-unsubscribe.js.es6 b/app/assets/javascripts/discourse/routes/topic-unsubscribe.js.es6 index 26e476af233..2faf69d0fb5 100644 --- a/app/assets/javascripts/discourse/routes/topic-unsubscribe.js.es6 +++ b/app/assets/javascripts/discourse/routes/topic-unsubscribe.js.es6 @@ -1,4 +1,4 @@ -import { loadTopicView } from "discourse/models/post-stream"; +import { loadTopicView } from 'discourse/models/topic'; export default Discourse.Route.extend({ model(params) { @@ -7,7 +7,6 @@ export default Discourse.Route.extend({ }, afterModel(topic) { - // hide the notification reason text topic.set("details.notificationReasonText", null); }, diff --git a/app/assets/javascripts/main_include.js b/app/assets/javascripts/main_include.js index a4d939f1a40..4858e420194 100644 --- a/app/assets/javascripts/main_include.js +++ b/app/assets/javascripts/main_include.js @@ -46,6 +46,7 @@ //= require ./discourse/models/post-action-type //= require ./discourse/models/action-summary //= require ./discourse/models/post +//= require ./discourse/lib/posts-with-placeholders //= require ./discourse/models/post-stream //= require ./discourse/models/topic-details //= require ./discourse/models/topic