From 4b53fe3cc7a8dc7c1532031ad82a6f6aa45ce907 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20Hanol?= Date: Sat, 5 Aug 2017 02:23:35 +0200 Subject: [PATCH] new 'addNavigationBarItem' plugin api --- .../discourse/lib/plugin-api.js.es6 | 19 +++- .../discourse/models/nav-item.js.es6 | 91 +++++++++++-------- 2 files changed, 72 insertions(+), 38 deletions(-) diff --git a/app/assets/javascripts/discourse/lib/plugin-api.js.es6 b/app/assets/javascripts/discourse/lib/plugin-api.js.es6 index b96b5514218..17e1456dea7 100644 --- a/app/assets/javascripts/discourse/lib/plugin-api.js.es6 +++ b/app/assets/javascripts/discourse/lib/plugin-api.js.es6 @@ -20,10 +20,11 @@ import { addPostClassesCallback } from 'discourse/widgets/post'; import { addPostTransformCallback } from 'discourse/widgets/post-stream'; import { attachAdditionalPanel } from 'discourse/widgets/header'; import { registerIconRenderer } from 'discourse-common/lib/icon-library'; +import { addNavItem } from 'discourse/models/nav-item'; // If you add any methods to the API ensure you bump up this number -const PLUGIN_API_VERSION = '0.8.8'; +const PLUGIN_API_VERSION = '0.8.9'; class PluginApi { constructor(version, container) { @@ -524,6 +525,22 @@ class PluginApi { addPostTransformCallback(callback) { addPostTransformCallback(callback); } + + /** + * + * Adds a new item in the navigation bar. + * + * Example: + * + * addNavigationBarItem({ + * name: "discourse", + * displayName: "Discourse" + * href: "https://www.discourse.org", + * }) + */ + addNavigationBarItem(item) { + addNavItem(item); + } } let _pluginv01; diff --git a/app/assets/javascripts/discourse/models/nav-item.js.es6 b/app/assets/javascripts/discourse/models/nav-item.js.es6 index d28b6728345..5015496284e 100644 --- a/app/assets/javascripts/discourse/models/nav-item.js.es6 +++ b/app/assets/javascripts/discourse/models/nav-item.js.es6 @@ -1,83 +1,92 @@ import { toTitleCase } from 'discourse/lib/formatter'; +import computed from 'ember-addons/ember-computed-decorators'; const NavItem = Discourse.Model.extend({ - displayName: function() { - var categoryName = this.get('categoryName'), - name = this.get('name'), - count = this.get('count') || 0; + @computed("categoryName", "name", "count") + displayName(categoryName, name, count) { + count = count || 0; if (name === 'latest' && !Discourse.Site.currentProp('mobileView')) { count = 0; } - var extra = { count: count }; - var titleKey = count === 0 ? '.title' : '.title_with_count'; + let extra = { count: count }; + const titleKey = count === 0 ? '.title' : '.title_with_count'; if (categoryName) { name = 'category'; extra.categoryName = toTitleCase(categoryName); } - return I18n.t("filters." + name.replace("/", ".") + titleKey, extra); - }.property('categoryName', 'name', 'count'), - categoryName: function() { - var split = this.get('name').split('/'); + return I18n.t(`filters.${name.replace("/", ".") + titleKey}`, extra); + }, + + @computed("name") + categoryName(name) { + const split = name.split('/'); return split[0] === 'category' ? split[1] : null; - }.property('name'), + }, - categorySlug: function() { - var split = this.get('name').split('/'); + @computed("name") + categorySlug(name) { + const split = name.split('/'); if (split[0] === 'category' && split[1]) { - var cat = Discourse.Site.current().categories.findBy('nameLower', split[1].toLowerCase()); + const cat = Discourse.Site.current().categories.findBy('nameLower', split[1].toLowerCase()); return cat ? Discourse.Category.slugFor(cat) : null; } return null; - }.property('name'), + }, + + @computed("filterMode") + href(filterMode) { + let customHref = null; - href: function() { - var customHref = null; _.each(NavItem.customNavItemHrefs, function(cb) { customHref = cb.call(this, this); if (customHref) { return false; } }, this); + if (customHref) { return customHref; } - return Discourse.getURL("/") + this.get('filterMode'); - }.property('filterMode'), - // href from this item - filterMode: function() { - var name = this.get('name'); + return Discourse.getURL("/") + filterMode; + }, - if( name.split('/')[0] === 'category' ) { - return 'c/' + this.get('categorySlug'); + @computed("name", "category", "categorySlug", "noSubcategories") + filterMode(name, category, categorySlug, noSubcategories) { + if (name.split('/')[0] === 'category') { + return 'c/' + categorySlug; } else { - var mode = "", - category = this.get("category"); - - if(category){ + let mode = ""; + if (category) { mode += "c/"; - mode += Discourse.Category.slugFor(this.get('category')); - if (this.get('noSubcategories')) { mode += '/none'; } + mode += Discourse.Category.slugFor(category); + if (noSubcategories) { mode += '/none'; } mode += "/l/"; } return mode + name.replace(' ', '-'); } - }.property('name'), + }, - count: function() { - var state = this.get('topicTrackingState'); + @computed("topicTrackingState", "name", "category") + count(state, name, category) { if (state) { - return state.lookupCount(this.get('name'), this.get('category')); + return state.lookupCount(name, category); } - }.property('topicTrackingState.messageCount') + } }); + const ExtraNavItem = NavItem.extend({ + @computed("href") + href: (href) => href +}); + NavItem.reopenClass({ extraArgsCallbacks: [], customNavItemHrefs: [], + extraNavItems: [], // create a nav item from the text, will return null if there is not valid nav item for this particular text fromText(text, opts) { @@ -113,16 +122,24 @@ NavItem.reopenClass({ items.push(args.filterMode); } - return items.map(i => Discourse.NavItem.fromText(i, args)) - .filter(i => i !== null && !(category && i.get("name").indexOf("categor") === 0)); + items = items.map(i => Discourse.NavItem.fromText(i, args)) + .filter(i => i !== null && !(category && i.get("name").indexOf("categor") === 0)); + + return items.concat(NavItem.extraNavItems); } }); export default NavItem; + export function extraNavItemProperties(cb) { NavItem.extraArgsCallbacks.push(cb); } + export function customNavItemHref(cb) { NavItem.customNavItemHrefs.push(cb); } + +export function addNavItem(item) { + NavItem.extraNavItems.push(ExtraNavItem.create(item)); +}