Convert Notification button to a component

This commit is contained in:
Robin Ward 2015-02-26 11:32:50 -05:00
parent 3c3e08147b
commit 1f716f5514
10 changed files with 54 additions and 91 deletions

View File

@ -1,4 +1,4 @@
import NotificationsButton from 'discourse/views/notifications-button'; import NotificationsButton from 'discourse/components/notifications-button';
export default NotificationsButton.extend({ export default NotificationsButton.extend({
classNames: ['notification-options', 'category-notification-menu'], classNames: ['notification-options', 'category-notification-menu'],
@ -10,7 +10,7 @@ export default NotificationsButton.extend({
i18nPrefix: 'category.notifications', i18nPrefix: 'category.notifications',
i18nPostfix: '', i18nPostfix: '',
clicked: function(id) { clicked(id) {
this.get('category').setNotification(id); this.get('category').setNotification(id);
} }
}); });

View File

@ -1,13 +1,13 @@
import StringBuffer from 'discourse/mixins/string-buffer'; import StringBuffer from 'discourse/mixins/string-buffer';
export default Discourse.View.extend(StringBuffer, { export default Ember.Component.extend(StringBuffer, {
classNameBindings: [':btn-group', 'hidden'], classNameBindings: [':btn-group', 'hidden'],
rerenderTriggers: ['text', 'longDescription'], rerenderTriggers: ['text', 'longDescription'],
_bindClick: function() { _bindClick: function() {
// If there's a click handler, call it // If there's a click handler, call it
if (this.clicked) { if (this.clicked) {
var self = this; const self = this;
this.$().on('click.dropdown-button', 'ul li', function(e) { this.$().on('click.dropdown-button', 'ul li', function(e) {
e.preventDefault(); e.preventDefault();
if ($(e.currentTarget).data('id') !== self.get('activeItem')) { if ($(e.currentTarget).data('id') !== self.get('activeItem')) {
@ -23,7 +23,7 @@ export default Discourse.View.extend(StringBuffer, {
this.$().off('click.dropdown-button', 'ul li'); this.$().off('click.dropdown-button', 'ul li');
}.on('willDestroyElement'), }.on('willDestroyElement'),
renderString: function(buffer) { renderString(buffer) {
buffer.push("<h4 class='title'>" + this.get('title') + "</h4>"); buffer.push("<h4 class='title'>" + this.get('title') + "</h4>");
buffer.push("<button class='btn standard dropdown-toggle' data-toggle='dropdown'>"); buffer.push("<button class='btn standard dropdown-toggle' data-toggle='dropdown'>");
@ -31,27 +31,24 @@ export default Discourse.View.extend(StringBuffer, {
buffer.push("</button>"); buffer.push("</button>");
buffer.push("<ul class='dropdown-menu'>"); buffer.push("<ul class='dropdown-menu'>");
var contents = this.get('dropDownContent'); const contents = this.get('dropDownContent');
if (contents) { if (contents) {
var self = this; const self = this;
contents.forEach(function(row) { contents.forEach(function(row) {
var id = row.id, const id = row.id,
title = row.title,
iconClass = row.styleClasses,
description = row.description,
className = (self.get('activeItem') === id ? 'disabled': ''); className = (self.get('activeItem') === id ? 'disabled': '');
buffer.push("<li data-id=\"" + id + "\" class=\"" + className + "\"><a href>"); buffer.push("<li data-id=\"" + id + "\" class=\"" + className + "\"><a href>");
buffer.push("<span class='icon " + iconClass + "'></span>"); buffer.push("<span class='icon " + row.styleClasses + "'></span>");
buffer.push("<div><span class='title'>" + title + "</span>"); buffer.push("<div><span class='title'>" + row.title + "</span>");
buffer.push("<span>" + description + "</span></div>"); buffer.push("<span>" + row.description + "</span></div>");
buffer.push("</a></li>"); buffer.push("</a></li>");
}); });
} }
buffer.push("</ul>"); buffer.push("</ul>");
var desc = this.get('longDescription'); const desc = this.get('longDescription');
if (desc) { if (desc) {
buffer.push("<p>"); buffer.push("<p>");
buffer.push(desc); buffer.push(desc);

View File

@ -1,6 +1,6 @@
import DropdownButtonView from 'discourse/views/dropdown-button'; import DropdownButton from 'discourse/components/dropdown-button';
export default DropdownButtonView.extend({ export default DropdownButton.extend({
classNames: ['notification-options'], classNames: ['notification-options'],
title: '', title: '',
buttonIncludesText: true, buttonIncludesText: true,
@ -21,7 +21,7 @@ export default DropdownButtonView.extend({
}.property(), }.property(),
dropDownContent: function() { dropDownContent: function() {
var contents = [], const contents = [],
prefix = this.get('i18nPrefix'), prefix = this.get('i18nPrefix'),
postfix = this.get('i18nPostfix'), postfix = this.get('i18nPostfix'),
levels = this.get('notificationLevels'); levels = this.get('notificationLevels');
@ -40,12 +40,12 @@ export default DropdownButtonView.extend({
}.property(), }.property(),
text: function() { text: function() {
var self = this, const self = this,
prefix = this.get('i18nPrefix'), prefix = this.get('i18nPrefix'),
postfix = this.get('i18nPostfix'), postfix = this.get('i18nPostfix'),
levels = this.get('notificationLevels'); levels = this.get('notificationLevels');
var key = (function() { const key = (function() {
switch (this.get('notificationLevel')) { switch (this.get('notificationLevel')) {
case levels.WATCHING: return 'watching'; case levels.WATCHING: return 'watching';
case levels.TRACKING: return 'tracking'; case levels.TRACKING: return 'tracking';
@ -54,7 +54,7 @@ export default DropdownButtonView.extend({
} }
}).call(this); }).call(this);
var icon = (function() { const icon = (function() {
switch (key) { switch (key) {
case 'watching': return '<i class="' + self.watchingClasses + '"></i>&nbsp;'; case 'watching': return '<i class="' + self.watchingClasses + '"></i>&nbsp;';
case 'tracking': return '<i class="' + self.trackingClasses + '"></i>&nbsp;'; case 'tracking': return '<i class="' + self.trackingClasses + '"></i>&nbsp;';
@ -65,7 +65,7 @@ export default DropdownButtonView.extend({
return icon + ( this.get('buttonIncludesText') ? I18n.t(prefix + '.' + key + postfix + ".title") : '') + "<span class='caret'></span>"; return icon + ( this.get('buttonIncludesText') ? I18n.t(prefix + '.' + key + postfix + ".title") : '') + "<span class='caret'></span>";
}.property('notificationLevel'), }.property('notificationLevel'),
clicked: function(/* id */) { clicked(/* id */) {
// sub-class needs to implement this // sub-class needs to implement this
} }

View File

@ -1,22 +1,20 @@
import DropdownButtonView from 'discourse/views/dropdown-button'; import DropdownButton from 'discourse/components/dropdown-button';
export default DropdownButtonView.extend({ export default DropdownButton.extend({
descriptionKey: 'help', descriptionKey: 'help',
classNames: ['pinned-options'], classNames: ['pinned-options'],
title: '', title: '',
longDescription: function(){ longDescription: function(){
var topic = this.get('topic'); const topic = this.get('topic');
var globally = topic.get('pinned_globally') ? '_globally' : ''; const globally = topic.get('pinned_globally') ? '_globally' : '';
const key = 'topic_statuses.' + (topic.get('pinned') ? 'pinned' + globally : 'unpinned') + '.help';
var key = 'topic_statuses.' + (topic.get('pinned') ? 'pinned' + globally : 'unpinned') + '.help';
return I18n.t(key); return I18n.t(key);
}.property('topic.pinned'), }.property('topic.pinned'),
topic: Em.computed.alias('controller.model'),
target: Em.computed.alias('topic'), target: Em.computed.alias('topic'),
hidden: function(){ hidden: function(){
var topic = this.get('topic'); const topic = this.get('topic');
return topic.get('deleted') || (!topic.get('pinned') && !topic.get('unpinned')); return topic.get('deleted') || (!topic.get('pinned') && !topic.get('unpinned'));
}.property('topic.pinned', 'topic.deleted', 'topic.unpinned'), }.property('topic.pinned', 'topic.deleted', 'topic.unpinned'),
@ -25,7 +23,7 @@ export default DropdownButtonView.extend({
}.property('topic.pinned'), }.property('topic.pinned'),
dropDownContent: function() { dropDownContent: function() {
var globally = this.get('topic.pinned_globally') ? '_globally' : ''; const globally = this.get('topic.pinned_globally') ? '_globally' : '';
return [ return [
{id: 'pinned', {id: 'pinned',
title: I18n.t('topic_statuses.pinned' + globally + '.title'), title: I18n.t('topic_statuses.pinned' + globally + '.title'),
@ -39,15 +37,15 @@ export default DropdownButtonView.extend({
}.property(), }.property(),
text: function() { text: function() {
var globally = this.get('topic.pinned_globally') ? '_globally' : ''; const globally = this.get('topic.pinned_globally') ? '_globally' : '';
var state = this.get('topic.pinned') ? 'pinned' + globally : 'unpinned'; const state = this.get('topic.pinned') ? 'pinned' + globally : 'unpinned';
return '<span class="fa fa-thumb-tack' + (state === 'unpinned' ? ' unpinned' : "") + '"></span> ' + return '<span class="fa fa-thumb-tack' + (state === 'unpinned' ? ' unpinned' : "") + '"></span> ' +
I18n.t('topic_statuses.' + state + '.title') + "<span class='caret'></span>"; I18n.t('topic_statuses.' + state + '.title') + "<span class='caret'></span>";
}.property('topic.pinned', 'topic.unpinned'), }.property('topic.pinned', 'topic.unpinned'),
clicked: function(id) { clicked(id) {
var topic = this.get('topic'); const topic = this.get('topic');
if(id==='unpinned'){ if(id==='unpinned'){
topic.clearPin(); topic.clearPin();
} else { } else {

View File

@ -1,8 +1,7 @@
import NotificationsButton from 'discourse/views/notifications-button'; import NotificationsButton from 'discourse/components/notifications-button';
export default NotificationsButton.extend({ export default NotificationsButton.extend({
longDescriptionBinding: 'topic.details.notificationReasonText', longDescriptionBinding: 'topic.details.notificationReasonText',
topic: Em.computed.alias('controller.model'),
target: Em.computed.alias('topic'), target: Em.computed.alias('topic'),
hidden: Em.computed.alias('topic.deleted'), hidden: Em.computed.alias('topic.deleted'),
notificationLevels: Discourse.Topic.NotificationLevel, notificationLevels: Discourse.Topic.NotificationLevel,
@ -14,7 +13,7 @@ export default NotificationsButton.extend({
return this.get('isPrivateMessage') ? '_pm' : ''; return this.get('isPrivateMessage') ? '_pm' : '';
}.property('isPrivateMessage'), }.property('isPrivateMessage'),
clicked: function(id) { clicked(id) {
this.get('topic.details').updateNotifications(id); this.get('topic.details').updateNotifications(id);
} }
}); });

View File

@ -1,17 +0,0 @@
<div>
<button class='btn standard dropdown-toggle' data-toggle='dropdown'>
<i {{bind-attr class=view.icon}}></i>
<span class='caret'></span>
</button>
<ul class='notification-dropdown-menu'>
{{#each level in view.dropDownContent}}
<li data-id="{{level.id}}">
<a {{action "setNotification" level.id}} href="#">
<span class="title"><i {{bind-attr class=level.styleClasses}}></i>&nbsp;{{level.title}}</span><span>{{level.description}}</span>
</a>
</li>
{{/each}}
</ul>
</div>

View File

@ -11,7 +11,7 @@
</ul> </ul>
{{#if canChangeCategoryNotificationLevel}} {{#if canChangeCategoryNotificationLevel}}
{{view 'category-notifications-button' category=category}} {{category-notifications-button category=category}}
{{/if}} {{/if}}
{{#if canCreateTopic}} {{#if canCreateTopic}}

View File

@ -1,26 +1,11 @@
export default Ember.ContainerView.extend(Discourse.Presence, { export default Ember.ContainerView.extend(Discourse.Presence, {
/** attachViewWithArgs(viewArgs, viewClass) {
Attaches a view and wires up the container properly
@method attachViewWithArgs
@param {Object} viewArgs The arguments to pass when creating the view
@param {Class} viewClass The view class we want to create
**/
attachViewWithArgs: function(viewArgs, viewClass) {
if (!viewClass) { viewClass = Ember.View.extend(); } if (!viewClass) { viewClass = Ember.View.extend(); }
var view = this.createChildView(viewClass, viewArgs); this.pushObject(this.createChildView(viewClass, viewArgs));
this.pushObject(view);
}, },
/** attachViewClass(viewClass) {
Attaches a view with no arguments and wires up the container properly
@method attachViewClass
@param {Class} viewClass The view class we want to add
**/
attachViewClass: function(viewClass) {
this.attachViewWithArgs(null, viewClass); this.attachViewWithArgs(null, viewClass);
} }
}); });

View File

@ -5,23 +5,24 @@ import BookmarkButton from 'discourse/views/bookmark-button';
import ShareButton from 'discourse/views/share-button'; import ShareButton from 'discourse/views/share-button';
import InviteReplyButton from 'discourse/views/invite-reply-button'; import InviteReplyButton from 'discourse/views/invite-reply-button';
import ReplyButton from 'discourse/views/reply-button'; import ReplyButton from 'discourse/views/reply-button';
import PinnedButton from 'discourse/views/pinned-button'; import PinnedButton from 'discourse/components/pinned-button';
import TopicNotificationsButton from 'discourse/views/topic-notifications-button'; import TopicNotificationsButton from 'discourse/components/topic-notifications-button';
import DiscourseContainerView from 'discourse/views/container'; import DiscourseContainerView from 'discourse/views/container';
export default DiscourseContainerView.extend({ export default DiscourseContainerView.extend({
elementId: 'topic-footer-buttons', elementId: 'topic-footer-buttons',
topicBinding: 'controller.content', topicBinding: 'controller.content',
init: function() { init() {
this._super(); this._super();
this.createButtons(); this.createButtons();
}, },
// Add the buttons below a topic // Add the buttons below a topic
createButtons: function() { createButtons() {
var topic = this.get('topic'); const topic = this.get('topic');
if (Discourse.User.current()) { if (Discourse.User.current()) {
const viewArgs = {topic};
if (Discourse.User.currentProp("staff")) { if (Discourse.User.currentProp("staff")) {
this.attachViewClass(TopicAdminMenuButton); this.attachViewClass(TopicAdminMenuButton);
} }
@ -39,8 +40,8 @@ export default DiscourseContainerView.extend({
if (this.get('topic.details.can_create_post')) { if (this.get('topic.details.can_create_post')) {
this.attachViewClass(ReplyButton); this.attachViewClass(ReplyButton);
} }
this.attachViewClass(PinnedButton); this.attachViewWithArgs(viewArgs, PinnedButton);
this.attachViewClass(TopicNotificationsButton); this.attachViewWithArgs(viewArgs, TopicNotificationsButton);
this.trigger('additionalButtons', this); this.trigger('additionalButtons', this);
} else { } else {

View File

@ -42,9 +42,9 @@
//= require ./discourse/views/flag //= require ./discourse/views/flag
//= require ./discourse/views/combo-box //= require ./discourse/views/combo-box
//= require ./discourse/views/button //= require ./discourse/views/button
//= require ./discourse/views/dropdown-button //= require ./discourse/components/dropdown-button
//= require ./discourse/views/notifications-button //= require ./discourse/components/notifications-button
//= require ./discourse/views/topic-notifications-button //= require ./discourse/components/topic-notifications-button
//= require ./discourse/views/pagedown-preview //= require ./discourse/views/pagedown-preview
//= require ./discourse/views/composer //= require ./discourse/views/composer
//= require ./discourse/routes/discourse_route //= require ./discourse/routes/discourse_route