From f5332765079a9d20272df06a7181ce3c77a48d50 Mon Sep 17 00:00:00 2001 From: Sam Date: Fri, 10 Jul 2015 12:09:43 +1000 Subject: [PATCH] FIX: do not publish all categories when a category changes. minor fixes to UI, still needs more work for live refresh of category listing --- .../components/category-chooser.js.es6 | 22 ++++++++++--- .../subscribe-user-notifications.js.es6 | 3 ++ .../javascripts/discourse/lib/mobile.js | 4 +-- .../javascripts/discourse/models/site.js.es6 | 32 ++++++++++++++----- app/models/category.rb | 15 ++++++--- test/javascripts/models/site-test.js.es6 | 8 +++++ 6 files changed, 65 insertions(+), 19 deletions(-) diff --git a/app/assets/javascripts/discourse/components/category-chooser.js.es6 b/app/assets/javascripts/discourse/components/category-chooser.js.es6 index 856bcb4d1f4..57a7ed9697d 100644 --- a/app/assets/javascripts/discourse/components/category-chooser.js.es6 +++ b/app/assets/javascripts/discourse/components/category-chooser.js.es6 @@ -26,13 +26,25 @@ export default ComboboxView.extend({ }.property('scopedCategoryId', 'categories'), _setCategories: function() { - this.set('categories', this.get('categories') || ( - Discourse.SiteSettings.fixed_category_positions_on_create ? - Discourse.Category.list() : Discourse.Category.listByActivity() - ) - ); + + if (!this.get('categories')) { + this.set('automatic', true); + } + + this._updateCategories(); + }.on('init'), + _updateCategories: function() { + + if (this.get('automatic')) { + this.set('categories', + Discourse.SiteSettings.fixed_category_positions_on_create ? + Discourse.Category.list() : Discourse.Category.listByActivity() + ); + } + }.observes('automatic', 'site.sortedCategories'), + none: function() { if (Discourse.User.currentProp('staff') || Discourse.SiteSettings.allow_uncategorized_topics) { if (this.get('rootNone')) { diff --git a/app/assets/javascripts/discourse/initializers/subscribe-user-notifications.js.es6 b/app/assets/javascripts/discourse/initializers/subscribe-user-notifications.js.es6 index d9f5dfd292c..a45a5a3585b 100644 --- a/app/assets/javascripts/discourse/initializers/subscribe-user-notifications.js.es6 +++ b/app/assets/javascripts/discourse/initializers/subscribe-user-notifications.js.es6 @@ -58,6 +58,9 @@ export default { _.each(data.categories,function(c) { site.updateCategory(c); }); + _.each(data.deleted_categories,function(id) { + site.removeCategory(id); + }); }); if (!Ember.testing) { diff --git a/app/assets/javascripts/discourse/lib/mobile.js b/app/assets/javascripts/discourse/lib/mobile.js index cb51b58886a..688482fa447 100644 --- a/app/assets/javascripts/discourse/lib/mobile.js +++ b/app/assets/javascripts/discourse/lib/mobile.js @@ -14,10 +14,10 @@ Discourse.Mobile = { this.mobileView = $html.hasClass('mobile-view'); try{ - if (window.location.search.test(/mobile_view=1/)){ + if (window.location.search.match(/mobile_view=1/)){ localStorage.mobileView = true; } - if (window.location.search.test(/mobile_view=0/)){ + if (window.location.search.match(/mobile_view=0/)){ localStorage.mobileView = false; } if (localStorage.mobileView) { diff --git a/app/assets/javascripts/discourse/models/site.js.es6 b/app/assets/javascripts/discourse/models/site.js.es6 index b7bc4a4977c..e3466eada0f 100644 --- a/app/assets/javascripts/discourse/models/site.js.es6 +++ b/app/assets/javascripts/discourse/models/site.js.es6 @@ -18,9 +18,8 @@ const Site = Discourse.Model.extend({ return postActionTypes.filterProperty('is_flag', true); }.property('post_action_types.@each'), - categoriesByCount: Ember.computed.sort('categories', function(a, b) { - return (b.get('topic_count') || 0) - (a.get('topic_count') || 0); - }), + topicCountDesc: ['topic_count:desc'], + categoriesByCount: Ember.computed.sort('categories', 'topicCountDesc'), // Sort subcategories under parents sortedCategories: function() { @@ -48,7 +47,7 @@ const Site = Discourse.Model.extend({ }); return result; - }.property(), + }.property("categories.@each"), postActionTypeById(id) { return this.get("postActionByIdLookup.action" + id); @@ -58,13 +57,30 @@ const Site = Discourse.Model.extend({ return this.get("topicFlagByIdLookup.action" + id); }, - updateCategory(newCategory) { - const existingCategory = this.get('categories').findProperty('id', Em.get(newCategory, 'id')); + removeCategory(id) { + const categories = this.get('categories'); + const existingCategory = categories.findProperty('id', id); if (existingCategory) { - // Don't update null permissions - if (newCategory.permission === null) { delete newCategory.permission; } + categories.removeObject(existingCategory); + delete this.get('categoriesById').categoryId; + } + }, + updateCategory(newCategory) { + const categories = this.get('categories'); + const categoryId = Em.get(newCategory, 'id'); + const existingCategory = categories.findProperty('id', categoryId); + + // Don't update null permissions + if (newCategory.permission === null) { delete newCategory.permission; } + + if (existingCategory) { existingCategory.setProperties(newCategory); + } else { + // TODO insert in right order? + newCategory = Discourse.Category.create(newCategory); + categories.pushObject(newCategory); + this.get('categoriesById')[categoryId] = newCategory; } } }); diff --git a/app/models/category.rb b/app/models/category.rb index d431252b1d8..1f6424d71ab 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -37,8 +37,10 @@ class Category < ActiveRecord::Base before_save :downcase_email before_save :downcase_name after_create :create_category_definition - after_create :publish_categories_list - after_destroy :publish_categories_list + + after_save :publish_category + after_destroy :publish_category_deletion + after_update :rename_category_definition, if: :name_changed? after_save :publish_discourse_stylesheet @@ -233,8 +235,13 @@ SQL slug.present? ? self.slug : "#{self.id}-category" end - def publish_categories_list - MessageBus.publish('/categories', {categories: ActiveModel::ArraySerializer.new(Category.latest).as_json}) + def publish_category + group_ids = self.groups.pluck(:id) if self.read_restricted + MessageBus.publish('/categories', {categories: ActiveModel::ArraySerializer.new([self]).as_json}, group_ids: group_ids) + end + + def publish_category_deletion + MessageBus.publish('/categories', {deleted_categories: [self.id]}) end def parent_category_validator diff --git a/test/javascripts/models/site-test.js.es6 b/test/javascripts/models/site-test.js.es6 index 9dcc8ff1b66..fa38736aef7 100644 --- a/test/javascripts/models/site-test.js.es6 +++ b/test/javascripts/models/site-test.js.es6 @@ -24,6 +24,7 @@ test('create categories', function() { }); var categories = site.get('categories'); + site.get('sortedCategories'); present(categories, "The categories are present"); equal(categories.length, 3, "it loaded all three categories"); @@ -36,4 +37,11 @@ test('create categories', function() { present(subcategory, "it loaded the subcategory"); equal(subcategory.get('parentCategory'), parent, "it has associated the child with the parent"); + // remove invalid category and child + categories.removeObject(categories[2]); + categories.removeObject(categories[1]); + + equal(categories.length, site.get('categoriesByCount').length, "categories by count should change on removal"); + equal(categories.length, site.get('sortedCategories').length, "sorted categories should change on removal"); + });