WIP: Add notifications button to timeline
This commit is contained in:
parent
1e3e4a95fd
commit
9e1021dfa3
|
@ -1,73 +1,49 @@
|
|||
import DropdownButton from 'discourse/components/dropdown-button';
|
||||
import NotificationLevels from 'discourse/lib/notification-levels';
|
||||
import { all, buttonDetails } from 'discourse/lib/notification-levels';
|
||||
import { iconHTML } from 'discourse/helpers/fa-icon';
|
||||
import computed from 'ember-addons/ember-computed-decorators';
|
||||
|
||||
const NotificationsButton = DropdownButton.extend({
|
||||
export default DropdownButton.extend({
|
||||
classNames: ['notification-options'],
|
||||
title: '',
|
||||
buttonIncludesText: true,
|
||||
activeItem: Em.computed.alias('notificationLevel'),
|
||||
i18nPrefix: '',
|
||||
i18nPostfix: '',
|
||||
watchingClasses: 'fa fa-exclamation-circle watching',
|
||||
trackingClasses: 'fa fa-circle tracking',
|
||||
mutedClasses: 'fa fa-times-circle muted',
|
||||
regularClasses: 'fa fa-circle-o regular',
|
||||
|
||||
options: function() {
|
||||
return [['WATCHING', 'watching', this.watchingClasses],
|
||||
['TRACKING', 'tracking', this.trackingClasses],
|
||||
['REGULAR', 'regular', this.regularClasses],
|
||||
['MUTED', 'muted', this.mutedClasses]];
|
||||
}.property(),
|
||||
@computed
|
||||
dropDownContent() {
|
||||
const prefix = this.get('i18nPrefix');
|
||||
const postfix = this.get('i18nPostfix');
|
||||
|
||||
dropDownContent: function() {
|
||||
const contents = [],
|
||||
prefix = this.get('i18nPrefix'),
|
||||
postfix = this.get('i18nPostfix');
|
||||
|
||||
_.each(this.get('options'), function(pair) {
|
||||
if (postfix === '_pm' && pair[1] === 'regular') { return; }
|
||||
contents.push({
|
||||
id: NotificationLevels[pair[0]],
|
||||
title: I18n.t(prefix + '.' + pair[1] + postfix + '.title'),
|
||||
description: I18n.t(prefix + '.' + pair[1] + postfix + '.description'),
|
||||
styleClasses: pair[2]
|
||||
});
|
||||
return all.map(l => {
|
||||
const start = `${prefix}.${l.key}${postfix}`;
|
||||
return {
|
||||
id: l.id,
|
||||
title: I18n.t(`${start}.title`),
|
||||
description: I18n.t(`${start}.description`),
|
||||
styleClasses: `${l.key} fa fa-${l.icon}`
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
return contents;
|
||||
}.property(),
|
||||
@computed('notificationLevel')
|
||||
text(notificationLevel) {
|
||||
const details = buttonDetails(notificationLevel);
|
||||
const { key } = details;
|
||||
const icon = iconHTML(details.icon, { class: key });
|
||||
|
||||
text: function() {
|
||||
const self = this,
|
||||
prefix = this.get('i18nPrefix'),
|
||||
postfix = this.get('i18nPostfix');
|
||||
|
||||
const key = (function() {
|
||||
switch (this.get('notificationLevel')) {
|
||||
case NotificationLevels.WATCHING: return 'watching';
|
||||
case NotificationLevels.TRACKING: return 'tracking';
|
||||
case NotificationLevels.MUTED: return 'muted';
|
||||
default: return 'regular';
|
||||
}
|
||||
}).call(this);
|
||||
|
||||
const icon = (function() {
|
||||
switch (key) {
|
||||
case 'watching': return '<i class="' + self.watchingClasses + '"></i> ';
|
||||
case 'tracking': return '<i class="' + self.trackingClasses + '"></i> ';
|
||||
case 'muted': return '<i class="' + self.mutedClasses + '"></i> ';
|
||||
default: return '<i class="' + self.regularClasses + '"></i> ';
|
||||
}
|
||||
})();
|
||||
return icon + ( this.get('buttonIncludesText') ? I18n.t(prefix + '.' + key + postfix + ".title") : '') + "<span class='caret'></span>";
|
||||
}.property('notificationLevel'),
|
||||
if (this.get('buttonIncludesText')) {
|
||||
const prefix = this.get('i18nPrefix');
|
||||
const postfix = this.get('i18nPostfix');
|
||||
const text = I18n.t(`${prefix}.${key}${postfix}.title`);
|
||||
return `${icon} ${text}<span class='caret'></span>`;
|
||||
} else {
|
||||
return `${icon} <span class='caret'></span>`;
|
||||
}
|
||||
},
|
||||
|
||||
clicked(/* id */) {
|
||||
// sub-class needs to implement this
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
export default NotificationsButton;
|
||||
export { NotificationLevels };
|
||||
|
|
|
@ -1,6 +1,24 @@
|
|||
export default {
|
||||
const NotificationLevels = {
|
||||
WATCHING: 3,
|
||||
TRACKING: 2,
|
||||
REGULAR: 1,
|
||||
MUTED: 0
|
||||
};
|
||||
export default NotificationLevels;
|
||||
|
||||
export function buttonDetails(level) {
|
||||
switch(level) {
|
||||
case NotificationLevels.WATCHING:
|
||||
return { id: NotificationLevels.WATCHING, key: 'watching', icon: 'exclamation-circle' };
|
||||
case NotificationLevels.TRACKING:
|
||||
return { id: NotificationLevels.TRACKING, key: 'tracking', icon: 'circle' };
|
||||
case NotificationLevels.MUTED:
|
||||
return { id: NotificationLevels.MUTED, key: 'muted', icon: 'times-circle' };
|
||||
default:
|
||||
return { id: NotificationLevels.REGULAR, key: 'regular', icon: 'circle-o' };
|
||||
}
|
||||
}
|
||||
export const all = [ NotificationLevels.WATCHING,
|
||||
NotificationLevels.TRACKING,
|
||||
NotificationLevels.MUTED,
|
||||
NotificationLevels.DEFAULT ].map(buttonDetails);
|
||||
|
|
|
@ -30,12 +30,11 @@ export default createWidget('button', {
|
|||
|
||||
html(attrs) {
|
||||
const contents = [];
|
||||
|
||||
const left = !attrs.iconRight;
|
||||
if (attrs.icon && left) { contents.push(iconNode(attrs.icon)); }
|
||||
if (attrs.icon && left) { contents.push(iconNode(attrs.icon, { class: attrs.iconClass })); }
|
||||
if (attrs.label) { contents.push(I18n.t(attrs.label, attrs.labelOptions)); }
|
||||
if (attrs.contents) { contents.push(attrs.contents); }
|
||||
if (attrs.icon && !left) { contents.push(iconNode(attrs.icon)); }
|
||||
if (attrs.icon && !left) { contents.push(iconNode(attrs.icon, { class: attrs.iconClass })); }
|
||||
|
||||
return contents;
|
||||
},
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
import { createWidget } from 'discourse/widgets/widget';
|
||||
import { all, buttonDetails } from 'discourse/lib/notification-levels';
|
||||
import { h } from 'virtual-dom';
|
||||
|
||||
createWidget('notification-option', {
|
||||
buildKey: attrs => `topic-notifications-button-${attrs.id}`,
|
||||
tagName: 'li',
|
||||
|
||||
html(attrs) {
|
||||
return h('a', [
|
||||
h('span.icon', { className: `fa fa-${attrs.icon} ${attrs.key}`}),
|
||||
h('div', [
|
||||
h('span.title', I18n.t(`topic.notifications.${attrs.key}.title`)),
|
||||
h('span', I18n.t(`topic.notifications.${attrs.key}.description`)),
|
||||
])
|
||||
]);
|
||||
},
|
||||
|
||||
click() {
|
||||
this.sendWidgetAction('notificationLevelChanged', this.attrs.id);
|
||||
}
|
||||
});
|
||||
|
||||
export default createWidget('topic-notifications-button', {
|
||||
tagName: 'span.btn-group.notification-options',
|
||||
buildKey: () => `topic-notifications-button`,
|
||||
|
||||
defaultState() {
|
||||
return { expanded: false };
|
||||
},
|
||||
|
||||
buildClasses(attrs, state) {
|
||||
if (state.expanded) { return "open"; }
|
||||
},
|
||||
|
||||
buttonFor(level) {
|
||||
const details = buttonDetails(level);
|
||||
return this.attach('button', {
|
||||
className: `btn no-text`,
|
||||
icon: details.icon,
|
||||
action: 'toggleDropdown',
|
||||
iconClass: details.key
|
||||
});
|
||||
},
|
||||
|
||||
html(attrs, state) {
|
||||
const result = [ this.buttonFor(attrs.topic.get('details.notification_level')) ];
|
||||
if (state.expanded) {
|
||||
result.push(h('ul.dropdown-menu', all.map(l => this.attach('notification-option', l))));
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
toggleDropdown() {
|
||||
this.state.expanded = !this.state.expanded;
|
||||
},
|
||||
|
||||
clickOutside() {
|
||||
if (this.state.expanded) {
|
||||
this.sendWidgetAction('toggleDropdown');
|
||||
}
|
||||
},
|
||||
|
||||
notificationLevelChanged(id) {
|
||||
this.state.expanded = false;
|
||||
return this.attrs.topic.get('details').updateNotifications(id);
|
||||
}
|
||||
});
|
|
@ -225,7 +225,10 @@ export default createWidget('topic-timeline', {
|
|||
|
||||
const { currentUser } = this;
|
||||
if (currentUser && currentUser.get('canManageTopic')) {
|
||||
controls.push(this.attach('topic-admin-menu-button', { topic }));
|
||||
if (currentUser.get('canManageTopic')) {
|
||||
controls.push(this.attach('topic-admin-menu-button', { topic }));
|
||||
}
|
||||
controls.push(this.attach('topic-notifications-button', { topic }));
|
||||
}
|
||||
|
||||
return [ h('div.timeline-controls', controls),
|
||||
|
|
Loading…
Reference in New Issue