From 70815b024a53036ee2b39ab74f2f70d153cd0f58 Mon Sep 17 00:00:00 2001 From: Toby Zerner Date: Fri, 4 Sep 2015 12:15:11 +0930 Subject: [PATCH] Make Dropdown and NotificationsDropdown components more extensible --- .../src/components/NotificationsDropdown.js | 60 +++++++++++++------ js/lib/components/Dropdown.js | 16 +++-- less/forum/NotificationList.less | 22 ++++--- less/forum/NotificationsDropdown.less | 32 +++++----- 4 files changed, 79 insertions(+), 51 deletions(-) diff --git a/js/forum/src/components/NotificationsDropdown.js b/js/forum/src/components/NotificationsDropdown.js index 03fdefbfd..b55582915 100644 --- a/js/forum/src/components/NotificationsDropdown.js +++ b/js/forum/src/components/NotificationsDropdown.js @@ -1,8 +1,18 @@ -import Component from 'flarum/Component'; +import Dropdown from 'flarum/components/Dropdown'; import icon from 'flarum/helpers/icon'; import NotificationList from 'flarum/components/NotificationList'; -export default class NotificationsDropdown extends Component { +export default class NotificationsDropdown extends Dropdown { + static initProps(props) { + props.className = props.className || 'NotificationsDropdown'; + props.buttonClassName = props.buttonClassName || 'Button Button--flat'; + props.menuClassName = props.menuClassName || 'Dropdown-menu--right'; + props.label = props.label || app.trans('core.notifications'); + props.icon = props.icon || 'bell'; + + super.initProps(props); + } + constructor(...args) { super(...args); @@ -16,35 +26,51 @@ export default class NotificationsDropdown extends Component { this.list = new NotificationList(); } - view() { - const user = app.session.user; - const unread = user.unreadNotificationsCount(); + getButton() { + const unread = this.getUnreadCount(); + const vdom = super.getButton(); + vdom.attrs.className += (unread ? ' unread' : ''); + vdom.attrs.onclick = this.onclick.bind(this); + + return vdom; + } + + getButtonContent() { + const unread = this.getUnreadCount(); + + return [ + icon(this.props.icon, {className: 'Button-icon'}), + unread ? {unread} : '', + {this.props.label} + ]; + } + + getMenu() { return ( -
- - {unread || icon('bell')} - {app.trans('core.notifications')} - -
- {this.showing ? this.list.render() : ''} -
+
+ {this.showing ? this.list.render() : ''}
); } onclick() { if (app.drawer.isOpen()) { - m.route(app.route('notifications')); + this.goToRoute(); } else { this.showing = true; this.list.load(); } } + goToRoute() { + m.route(app.route('notifications')); + } + + getUnreadCount() { + return app.session.user.unreadNotificationsCount(); + } + menuClick(e) { // Don't close the notifications dropdown if the user is opening a link in a // new tab or window. diff --git a/js/lib/components/Dropdown.js b/js/lib/components/Dropdown.js index 027e91e82..16e3cc3ec 100644 --- a/js/lib/components/Dropdown.js +++ b/js/lib/components/Dropdown.js @@ -23,20 +23,18 @@ export default class Dropdown extends Component { props.className = props.className || ''; props.buttonClassName = props.buttonClassName || ''; - props.contentClassName = props.contentClassName || ''; + props.menuClassName = props.menuClassName || ''; props.label = props.label || app.trans('core.controls'); props.caretIcon = typeof props.caretIcon !== 'undefined' ? props.caretIcon : 'caret-down'; } view() { - const items = listItems(this.props.children); + const items = this.props.children ? listItems(this.props.children) : []; return (
{this.getButton()} -
    - {items} -
+ {this.getMenu(items)}
); } @@ -94,4 +92,12 @@ export default class Dropdown extends Component { this.props.caretIcon ? icon(this.props.caretIcon, {className: 'Button-caret'}) : '' ]; } + + getMenu(items) { + return ( + + ); + } } diff --git a/less/forum/NotificationList.less b/less/forum/NotificationList.less index d01964da8..e79c611f8 100644 --- a/less/forum/NotificationList.less +++ b/less/forum/NotificationList.less @@ -76,19 +76,17 @@ padding: 0; } .Notification { - > a { - display: block; - padding: 8px 15px 8px 70px; - color: @muted-color; - overflow: hidden; + display: block; + padding: 8px 15px 8px 70px; + color: @muted-color !important; // required to override .light-contents applied to header + overflow: hidden; - .unread& { - background: @control-bg; - } - &:hover { - text-decoration: none; - background: @control-bg; - } + .unread& { + background: @control-bg; + } + &:hover { + text-decoration: none; + background: @control-bg; } .Avatar { .Avatar--size(24px); diff --git a/less/forum/NotificationsDropdown.less b/less/forum/NotificationsDropdown.less index 551ca1c15..84384b585 100644 --- a/less/forum/NotificationsDropdown.less +++ b/less/forum/NotificationsDropdown.less @@ -24,21 +24,19 @@ } } -.NotificationsDropdown-button.unread .Button-icon { - display: inline-block; - border-radius: 12px; - height: 24px; - width: 24px; - text-align: center; - padding: 2px 0; - font-weight: bold; - margin: -2px 0; - background: @primary-color; - color: @body-bg; - font-size: 13px; - vertical-align: 0; - - & when (@config-colored-header = true) { - background: #fff; - } +.NotificationsDropdown .Dropdown-toggle.unread .Button-icon { + color: @header-color; +} +.NotificationsDropdown-unread { + position: absolute; + top: 1px; + right: 1px; + background: @header-color; + color: @header-bg; + font-size: 11px; + font-weight: bold; + padding: 2px 5px 3px; + line-height: 1em; + border-radius: 10px; + border: 1px solid @header-bg; }