From e503c3859a05a592ed566b2fb868e3bc36cf9837 Mon Sep 17 00:00:00 2001
From: Robin Ward <robin.ward@gmail.com>
Date: Thu, 19 Feb 2015 14:55:44 -0500
Subject: [PATCH] Allow plugins to change the header to show two rows

This allows the discourse-tagging plugin to correctly use two rows in
the header if it needs to display tags, or one row if there are no tags.
This works in tandem with the same logic for when there is a category
badge to display or not.
---
 .../components/header-extra-info.js.es6       | 47 +++++++++++++++++++
 .../discourse/controllers/header.js.es6       | 16 -------
 .../components/header-extra-info.hbs          | 21 +++++++++
 .../discourse/templates/header.hbs            | 27 +----------
 .../stylesheets/desktop/topic-post.scss       |  2 +-
 5 files changed, 70 insertions(+), 43 deletions(-)
 create mode 100644 app/assets/javascripts/discourse/components/header-extra-info.js.es6
 create mode 100644 app/assets/javascripts/discourse/templates/components/header-extra-info.hbs

diff --git a/app/assets/javascripts/discourse/components/header-extra-info.js.es6 b/app/assets/javascripts/discourse/components/header-extra-info.js.es6
new file mode 100644
index 000000000..a323d50df
--- /dev/null
+++ b/app/assets/javascripts/discourse/components/header-extra-info.js.es6
@@ -0,0 +1,47 @@
+const TopicCategoryComponent = Ember.Component.extend({
+  needsSecondRow: Ember.computed.gt('secondRowItems.length', 0),
+  secondRowItems: function() { return []; }.property(),
+
+  showPrivateMessageGlyph: function() {
+    return !this.get('topic.is_warning') && this.get('topic.isPrivateMessage');
+  }.property('topic.is_warning', 'topic.isPrivateMessage'),
+
+  actions: {
+    jumpToTopPost: function () {
+      var topic = this.get('topic');
+      if (topic) {
+        Discourse.URL.routeTo(topic.get('firstPostUrl'));
+      }
+    }
+  }
+
+});
+
+let id = 0;
+
+// Allow us (and plugins) to register themselves as needing a second
+// row in the header. If there is at least one thing in the second row
+// the style changes to accomodate it.
+function needsSecondRowIf(prop, cb) {
+  const rowId = "_second_row_" + (id++),
+        methodHash = {};
+
+  methodHash[id] = function() {
+    const secondRowItems = this.get('secondRowItems'),
+          propVal = this.get(prop);
+    if (cb.call(this, propVal)) {
+      secondRowItems.addObject(rowId);
+    } else {
+      secondRowItems.removeObject(rowId);
+    }
+  }.observes(prop).on('init');
+
+  TopicCategoryComponent.reopen(methodHash);
+}
+
+needsSecondRowIf('topic.category', function(cat) {
+  return cat && (!cat.get('isUncategorizedCategory') || !this.siteSettings.suppress_uncategorized_badge);
+});
+
+export default TopicCategoryComponent;
+export { needsSecondRowIf };
diff --git a/app/assets/javascripts/discourse/controllers/header.js.es6 b/app/assets/javascripts/discourse/controllers/header.js.es6
index 2511aa500..b40ac3efd 100644
--- a/app/assets/javascripts/discourse/controllers/header.js.es6
+++ b/app/assets/javascripts/discourse/controllers/header.js.es6
@@ -10,15 +10,6 @@ export default DiscourseController.extend({
   loginRequired: Em.computed.alias('controllers.application.loginRequired'),
   canSignUp: Em.computed.alias('controllers.application.canSignUp'),
 
-  hasCategory: function() {
-    var cat = this.get('topic.category');
-    return cat && (!cat.get('isUncategorizedCategory') || !this.siteSettings.suppress_uncategorized_badge);
-  }.property('topic.category'),
-
-  showPrivateMessageGlyph: function() {
-    return !this.get('topic.is_warning') && this.get('topic.isPrivateMessage');
-  }.property('topic.is_warning', 'topic.isPrivateMessage'),
-
   showSignUpButton: function() {
     return this.get('canSignUp') && !this.get('showExtraInfo');
   }.property('canSignUp', 'showExtraInfo'),
@@ -78,13 +69,6 @@ export default DiscourseController.extend({
         self.refreshNotifications();
       }
       headerView.showDropdownBySelector("#user-notifications");
-    },
-
-    jumpToTopPost: function () {
-      var topic = this.get('topic');
-      if (topic) {
-        Discourse.URL.routeTo(topic.get('firstPostUrl'));
-      }
     }
   }
 
diff --git a/app/assets/javascripts/discourse/templates/components/header-extra-info.hbs b/app/assets/javascripts/discourse/templates/components/header-extra-info.hbs
new file mode 100644
index 000000000..c6326286e
--- /dev/null
+++ b/app/assets/javascripts/discourse/templates/components/header-extra-info.hbs
@@ -0,0 +1,21 @@
+<div class="extra-info-wrapper">
+  <div {{bind-attr class=":extra-info needsSecondRow:two-rows"}}>
+    <div class="title-wrapper">
+      <h1>
+        {{#if showPrivateMessageGlyph}}
+          <span class="private-message-glyph">{{fa-icon "envelope"}}</span>
+        {{/if}}
+
+        {{#if topic.details.loaded}}
+          {{topic-status topic=topic}}
+          <a class='topic-link' href='{{unbound topic.url}}' {{action "jumpToTopPost"}}>{{{topic.fancy_title}}}</a>
+        {{else}}
+          {{#if topic.errorLoading}}
+            <span class="error">{{topic.errorTitle}}</span>
+          {{/if}}
+        {{/if}}
+      </h1>
+      {{topic-category topic=topic}}
+    </div>
+  </div>
+</div>
diff --git a/app/assets/javascripts/discourse/templates/header.hbs b/app/assets/javascripts/discourse/templates/header.hbs
index 7eec139b0..0299c69e9 100644
--- a/app/assets/javascripts/discourse/templates/header.hbs
+++ b/app/assets/javascripts/discourse/templates/header.hbs
@@ -77,9 +77,7 @@
       </ul>
 
       {{#if view.renderDropdowns}}
-
         {{render "search"}}
-
         {{render "notifications" notifications}}
 
         {{#if view.renderSiteMap}}
@@ -87,34 +85,11 @@
         {{/if}}
 
         {{render "user-dropdown"}}
-
       {{/if}}
-
     </div>
 
     {{#if showExtraInfo}}
-      <div class="extra-info-wrapper">
-        <div {{bind-attr class=":extra-info hasCategory"}}>
-          <div class="title-wrapper">
-            <h1>
-              {{#if showPrivateMessageGlyph}}
-                <span class="private-message-glyph">{{fa-icon "envelope"}}</span>
-              {{/if}}
-
-              {{#if topic.details.loaded}}
-                {{topic-status topic=topic}}
-                <a class='topic-link' href='{{unbound topic.url}}' {{action "jumpToTopPost"}}>{{{topic.fancy_title}}}</a>
-              {{else}}
-                {{#if topic.errorLoading}}
-                  <span class="error">{{topic.errorTitle}}</span>
-                {{/if}}
-              {{/if}}
-            </h1>
-            {{topic-category topic=topic}}
-          </div>
-        </div>
-      </div>
+      {{header-extra-info topic=topic}}
     {{/if}}
-
   </div>
 </div>
diff --git a/app/assets/stylesheets/desktop/topic-post.scss b/app/assets/stylesheets/desktop/topic-post.scss
index f547ad00f..6451a4e9b 100644
--- a/app/assets/stylesheets/desktop/topic-post.scss
+++ b/app/assets/stylesheets/desktop/topic-post.scss
@@ -577,7 +577,7 @@ video {
 }
 
 /* override docked header CSS for topics with categories */
-.extra-info.has-category {
+.extra-info.two-rows {
   h1 {
     line-height: 1.1em;
     margin: 0;