From dfe1a9bae5ceeba7f1f649d10559d59d6c89e3ae Mon Sep 17 00:00:00 2001 From: Toby Zerner Date: Tue, 23 Jun 2015 10:30:06 +0930 Subject: [PATCH] Gracefully handle discussions with no posts Although this should never happen --- framework/core/js/forum/src/components/post-scrubber.js | 6 +++--- framework/core/js/forum/src/components/post-stream.js | 8 ++++---- framework/core/js/lib/models/discussion.js | 2 +- framework/core/src/Api/Serializers/BaseSerializer.php | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/framework/core/js/forum/src/components/post-scrubber.js b/framework/core/js/forum/src/components/post-scrubber.js index 506eaa6e6..032761d46 100644 --- a/framework/core/js/forum/src/components/post-scrubber.js +++ b/framework/core/js/forum/src/components/post-scrubber.js @@ -135,7 +135,7 @@ export default class PostScrubber extends Component { // seen if the browser were scrolled right up to the top of the page, // and the viewport had a height of 0. var $items = stream.$('> .item[data-index]'); - var index = $items.first().data('index'); + var index = $items.first().data('index') || 0; var visible = 0; var period = ''; @@ -262,7 +262,7 @@ export default class PostScrubber extends Component { var percentPerPost = this.percentPerPost(); var index = this.index(); var count = this.count(); - var visible = this.visible(); + var visible = this.visible() || 1; var $scrubber = this.$(); $scrubber.find('.index').text(formatNumber(this.visibleIndex())); @@ -292,7 +292,7 @@ export default class PostScrubber extends Component { */ percentPerPost() { var count = this.count() || 1; - var visible = this.visible(); + var visible = this.visible() || 1; // To stop the slider of the scrollbar from getting too small when there // are many posts, we define a minimum percentage height for the slider diff --git a/framework/core/js/forum/src/components/post-stream.js b/framework/core/js/forum/src/components/post-stream.js index f0d369281..754511bdc 100644 --- a/framework/core/js/forum/src/components/post-stream.js +++ b/framework/core/js/forum/src/components/post-stream.js @@ -128,7 +128,7 @@ class PostStream extends mixin(Component, evented) { */ setup(posts) { this.posts = posts; - this.visibleStart = this.discussion.postIds().indexOf(posts[0].id()); + this.visibleStart = posts.length ? this.discussion.postIds().indexOf(posts[0].id()) : 0; this.visibleEnd = this.visibleStart + posts.length; } @@ -137,7 +137,7 @@ class PostStream extends mixin(Component, evented) { */ clear(start, end) { this.visibleStart = start || 0; - this.visibleEnd = end || this.constructor.loadCount; + this.visibleEnd = Math.min(this.count(), end || this.constructor.loadCount); this.posts = []; for (var i = this.visibleStart; i < this.visibleEnd; i++) { this.posts.push(null); @@ -234,7 +234,7 @@ class PostStream extends mixin(Component, evented) { if (this.visibleStart > 0) { var $item = this.$('.item[data-index='+this.visibleStart+']'); - if ($item.offset().top > viewportTop - loadAheadDistance) { + if ($item.length && $item.offset().top > viewportTop - loadAheadDistance) { this.loadPrevious(); } } @@ -242,7 +242,7 @@ class PostStream extends mixin(Component, evented) { if (this.visibleEnd < this.count()) { var $item = this.$('.item[data-index='+(this.visibleEnd - 1)+']'); - if ($item.offset().top + $item.outerHeight(true) < viewportTop + viewportHeight + loadAheadDistance) { + if ($item.length && $item.offset().top + $item.outerHeight(true) < viewportTop + viewportHeight + loadAheadDistance) { this.loadNext(); } } diff --git a/framework/core/js/lib/models/discussion.js b/framework/core/js/lib/models/discussion.js index b03461cbe..fe39bbf4a 100644 --- a/framework/core/js/lib/models/discussion.js +++ b/framework/core/js/lib/models/discussion.js @@ -58,7 +58,7 @@ Discussion.prototype.canRename = Model.prop('canRename'); Discussion.prototype.canDelete = Model.prop('canDelete'); Discussion.prototype.commentsCount = Model.prop('commentsCount'); -Discussion.prototype.repliesCount = computed('commentsCount', commentsCount => commentsCount - 1); +Discussion.prototype.repliesCount = computed('commentsCount', commentsCount => Math.max(0, commentsCount - 1)); Discussion.prototype.posts = Model.many('posts'); Discussion.prototype.postIds = function() { return this.data().links.posts.linkage.map((link) => link.id); }; diff --git a/framework/core/src/Api/Serializers/BaseSerializer.php b/framework/core/src/Api/Serializers/BaseSerializer.php index d7ebb33f4..dc3d1a9b4 100644 --- a/framework/core/src/Api/Serializers/BaseSerializer.php +++ b/framework/core/src/Api/Serializers/BaseSerializer.php @@ -58,7 +58,7 @@ abstract class BaseSerializer extends SerializerAbstract $data = $model->getRelation($relation); } elseif ($many) { $relationIds = $relation.'_ids'; - $data = $model->$relationIds ?: $model->$relation()->lists('id'); + $data = isset($model->$relationIds) ? $model->$relationIds : $model->$relation()->lists('id'); } else { $relationId = $relation.'_id'; $data = $model->$relationId;