From d8127a159063c52a0973edfaf0195fb5ab074818 Mon Sep 17 00:00:00 2001
From: Robin Ward <robin.ward@gmail.com>
Date: Thu, 10 Mar 2016 12:20:58 -0500
Subject: [PATCH] UX: Add icons to mobile Topic Controls drop down

---
 .../discourse/components/combo-box.js.es6     | 47 ++++++++-----------
 .../topic-footer-mobile-dropdown.js.es6       | 17 +++++--
 2 files changed, 32 insertions(+), 32 deletions(-)

diff --git a/app/assets/javascripts/discourse/components/combo-box.js.es6 b/app/assets/javascripts/discourse/components/combo-box.js.es6
index c314db566..83b9290bf 100644
--- a/app/assets/javascripts/discourse/components/combo-box.js.es6
+++ b/app/assets/javascripts/discourse/components/combo-box.js.es6
@@ -1,3 +1,5 @@
+import { on, observes } from 'ember-addons/ember-computed-decorators';
+
 export default Ember.Component.extend({
   tagName: 'select',
   attributeBindings: ['tabindex'],
@@ -5,16 +7,6 @@ export default Ember.Component.extend({
   valueAttribute: 'id',
   nameProperty: 'name',
 
-  _buildData(o) {
-    let result = "";
-    if (this.resultAttributes) {
-      this.resultAttributes.forEach(function(a) {
-        result += "data-" + a + "=\"" + o.get(a) + "\" ";
-      });
-    }
-    return result;
-  },
-
   render(buffer) {
     const nameProperty = this.get('nameProperty');
     const none = this.get('none');
@@ -23,27 +15,27 @@ export default Ember.Component.extend({
     if (typeof none === "string") {
       buffer.push('<option value="">' + I18n.t(none) + "</option>");
     } else if (typeof none === "object") {
-      buffer.push("<option value=\"\" " + this._buildData(none) + ">" + Em.get(none, nameProperty) + "</option>");
+      buffer.push("<option value=\"\">" + Em.get(none, nameProperty) + "</option>");
     }
 
     let selected = this.get('value');
     if (!Em.isNone(selected)) { selected = selected.toString(); }
 
     if (this.get('content')) {
-      const self = this;
-      this.get('content').forEach(function(o) {
-        let val = o[self.get('valueAttribute')];
+      this.get('content').forEach(o => {
+        let val = o[this.get('valueAttribute')];
         if (typeof val === "undefined") { val = o; }
         if (!Em.isNone(val)) { val = val.toString(); }
 
         const selectedText = (val === selected) ? "selected" : "";
-        const name = Ember.get(o, nameProperty) || o;
-        buffer.push("<option " + selectedText + " value=\"" + val + "\" " + self._buildData(o) + ">" + Handlebars.Utils.escapeExpression(name) + "</option>");
+        const name = Handlebars.Utils.escapeExpression(Ember.get(o, nameProperty) || o);
+        buffer.push(`<option ${selectedText} value="${val}">${name}</option>`);
       });
     }
   },
 
-  valueChanged: function() {
+  @observes('value')
+  valueChanged() {
     const $combo = this.$(),
           val = this.get('value');
 
@@ -52,19 +44,19 @@ export default Ember.Component.extend({
     } else {
       $combo.select2('val', null);
     }
-  }.observes('value'),
+  },
 
-  _rerenderOnChange: function() {
+  @observes('content.@each')
+  _rerenderOnChange() {
     this.rerender();
-  }.observes('content.@each'),
+  },
 
-  _initializeCombo: function() {
+  @on('didInsertElement')
+  _initializeCombo() {
 
     // Workaround for https://github.com/emberjs/ember.js/issues/9813
     // Can be removed when fixed. Without it, the wrong option is selected
-    this.$('option').each(function(i, o) {
-      o.selected = !!$(o).attr('selected');
-    });
+    this.$('option').each((i, o) => o.selected = !!$(o).attr('selected'));
 
     // observer for item names changing (optional)
     if (this.get('nameChanges')) {
@@ -84,10 +76,11 @@ export default Ember.Component.extend({
       this.set('value', val);
     });
     $elem.trigger('change');
-  }.on('didInsertElement'),
+  },
 
-  _destroyDropdown: function() {
+  @on('willDestroyElement')
+  _destroyDropdown() {
     this.$().select2('destroy');
-  }.on('willDestroyElement')
+  }
 
 });
diff --git a/app/assets/javascripts/discourse/components/topic-footer-mobile-dropdown.js.es6 b/app/assets/javascripts/discourse/components/topic-footer-mobile-dropdown.js.es6
index a975ade19..bd7ce01b1 100644
--- a/app/assets/javascripts/discourse/components/topic-footer-mobile-dropdown.js.es6
+++ b/app/assets/javascripts/discourse/components/topic-footer-mobile-dropdown.js.es6
@@ -1,3 +1,4 @@
+import { iconHTML } from 'discourse/helpers/fa-icon';
 import Combobox from 'discourse/components/combo-box';
 import { on, observes } from 'ember-addons/ember-computed-decorators';
 
@@ -11,20 +12,26 @@ export default Combobox.extend({
     const details = topic.get('details');
 
     if (details.get('can_invite_to')) {
-      content.push({ id: 'invite', name: I18n.t('topic.invite_reply.title') });
+      content.push({ id: 'invite', icon: 'users', name: I18n.t('topic.invite_reply.title') });
     }
 
     if (topic.get('bookmarked')) {
-      content.push({ id: 'bookmark', name: I18n.t('bookmarked.clear_bookmarks') });
+      content.push({ id: 'bookmark', icon: 'bookmark', name: I18n.t('bookmarked.clear_bookmarks') });
     } else {
-      content.push({ id: 'bookmark', name: I18n.t('bookmarked.title') });
+      content.push({ id: 'bookmark', icon: 'bookmark', name: I18n.t('bookmarked.title') });
     }
-    content.push({ id: 'share', name: I18n.t('topic.share.title') });
+    content.push({ id: 'share', icon: 'link', name: I18n.t('topic.share.title') });
 
     if (details.get('can_flag_topic')) {
-      content.push({ id: 'flag', name: I18n.t('topic.flag_topic.title') });
+      content.push({ id: 'flag', icon: 'flag', name: I18n.t('topic.flag_topic.title') });
     }
 
+    this.comboTemplate = (item) => {
+      const contentItem = content.findProperty('id', item.id);
+      if (!contentItem) { return item.text; }
+      return `${iconHTML(contentItem.icon)}&nbsp; ${item.text}`;
+    };
+
     this.set('content', content);
   },