Added proper badge support for mobile menu
authorAlexander Ebert <ebert@woltlab.com>
Wed, 17 Aug 2016 15:24:19 +0000 (17:24 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Wed, 17 Aug 2016 15:24:23 +0000 (17:24 +0200)
com.woltlab.wcf/templates/pageMenuMobile.tpl
wcfsetup/install/files/js/WCF.User.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Menu/Abstract.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Menu/User.js
wcfsetup/install/files/style/layout/pageHeader.scss
wcfsetup/install/files/style/ui/menuMobile.scss

index 04f22c351fafb9c77687132600ebed39698918fd..05496375052e5c8eacd77d5d9b237c32fc3b5a0e 100644 (file)
                        {/if}
                        <li class="menuOverlayItemSpacer"></li>
                        <li class="menuOverlayItem" data-more="com.woltlab.wcf.notifications">
-                               <a href="{link controller='NotificationList'}{/link}" class="menuOverlayItemLink box24">
+                               <a href="{link controller='NotificationList'}{/link}" class="menuOverlayItemLink menuOverlayItemBadge box24" data-badge-identifier="userNotifications">
                                        <span class="icon icon24 fa-bell-o"></span>
                                        <span class="menuOverlayItemTitle">{lang}wcf.user.notification.notifications{/lang}</span>
+                                       {if $__wcf->getUserNotificationHandler()->getNotificationCount()}<span class="badge badgeUpdate">{#$__wcf->getUserNotificationHandler()->getNotificationCount()}</span>{/if}
                                </a>
                        </li>
                        {if $__wcf->user->userID && $__wcf->session->getPermission('mod.general.canUseModeration')}
                                <li class="menuOverlayItem" data-more="com.woltlab.wcf.moderation">
-                                       <a href="#" class="menuOverlayItemLink box24">
+                                       <a href="#" class="menuOverlayItemLink menuOverlayItemBadge box24" data-badge-identifier="outstandingModeration">
                                                <span class="icon icon24 fa-exclamation-triangle"></span>
                                                <span class="menuOverlayItemTitle">{lang}wcf.moderation.moderation{/lang}</span>
+                                               {if $__wcf->getModerationQueueManager()->getOutstandingModerationCount()}<span class="badge badgeUpdate">{#$__wcf->getModerationQueueManager()->getOutstandingModerationCount()}</span>{/if}
                                        </a>
                                </li>
                        {/if}
index aa8d0b9cfddf23729ebfbb8a660d0defdd9c9ef5..c87c4405587fb6fa977da1e2d87c348216376c9d 100644 (file)
@@ -402,6 +402,11 @@ WCF.User.Panel.Abstract = Class.extend({
                                this._markAllAsReadLink = null;
                        }
                }
+               
+               WCF.System.Event.fireEvent('com.woltlab.wcf.userMenu', 'updateBadge', {
+                       count: count,
+                       identifier: this._identifier
+               });
        },
        
        /**
index 2ceb9da6b7f148d9329c9661095d0845e45118d6..4cf5f5d9060756e7ca9554d94b20ac1f7e5252c9 100644 (file)
@@ -36,8 +36,8 @@ define(['Environment', 'EventHandler', 'ObjectMap', 'Dom/Traverse', 'Dom/Util',
                        this._removeActiveList = false;
                        
                        var callbackOpen = this.open.bind(this);
-                       var button = elBySel(buttonSelector);
-                       button.addEventListener(WCF_CLICK_EVENT, callbackOpen);
+                       this._button = elBySel(buttonSelector);
+                       this._button.addEventListener(WCF_CLICK_EVENT, callbackOpen);
                        
                        this._initItems();
                        this._initHeader();
@@ -76,6 +76,8 @@ define(['Environment', 'EventHandler', 'ObjectMap', 'Dom/Traverse', 'Dom/Util',
                        backdrop.addEventListener(WCF_CLICK_EVENT, this.close.bind(this));
                        
                        DomUtil.insertAfter(backdrop, this._menu);
+                       
+                       this._updateButtonState();
                },
                
                /**
@@ -368,6 +370,17 @@ define(['Environment', 'EventHandler', 'ObjectMap', 'Dom/Traverse', 'Dom/Util',
                        this._depth += (increase) ? 1 : -1;
                        
                        this._menu.children[0].style.setProperty('transform', 'translateX(' + (this._depth * -100) + '%)', '');
+               },
+               
+               _updateButtonState: function() {
+                       var hasNewContent = false;
+                       elBySelAll('.badgeUpdate', this._menu, function (badge) {
+                               if (~~badge.textContent > 0) {
+                                       hasNewContent = true;
+                               }
+                       });
+                       
+                       this._button.classList[(hasNewContent ? 'add' : 'remove')]('pageMenuMobileButtonHasContent');
                }
        };
        
index 5392ef760e674da9b235803c6b4704cd82544c29..bfe10c28aa4da5f3f466239e906f229ccdf9020a 100644 (file)
@@ -24,6 +24,28 @@ define(['Core', 'EventHandler', './Abstract'], function(Core, EventHandler, UiPa
                                'pageUserMenuMobile',
                                '#pageHeader .userPanel'
                        );
+                       
+                       EventHandler.add('com.woltlab.wcf.userMenu', 'updateBadge', (function (data) {
+                               elBySelAll('.menuOverlayItemBadge', this._menu, (function (item) {
+                                       if (elData(item, 'badge-identifier') === data.identifier) {
+                                               var badge = elBySel('.badge', item);
+                                               if (data.count) {
+                                                       if (badge === null) {
+                                                               badge = elCreate('span');
+                                                               badge.className = 'badge badgeUpdate';
+                                                               item.appendChild(badge);
+                                                       }
+                                                       
+                                                       badge.textContent = data.count;
+                                               }
+                                               else if (badge !== null) {
+                                                       elRemove(badge);
+                                               }
+                                               
+                                               this._updateButtonState();
+                                       }
+                               }).bind(this));
+                       }).bind(this));
                }
        });
        
index f07716dd1f78c49ec737247f6ce91f56ca37188c..ec39766478ae2784a4a87e744036f328a49b0d9a 100644 (file)
        }
 }
 
+@keyframes wcfMobileMenuNewContent {
+       0%   { box-shadow: 0 0 0 rgba(255, 0, 0, 0); }
+       25%  { box-shadow: 0 0 0 rgba(255, 0, 0, 1); }
+       50%  { box-shadow: 0 0 10px rgba(255, 0, 0, 1); }
+       75%  { box-shadow: 0 0 0 rgba(255, 0, 0, 1); }
+       100% { box-shadow: 0 0 0 rgba(255, 0, 0, 0); }
+}
+
 @include screen-md-down {
        .pageHeader > div > div {
                padding-bottom: 10px;
        .userPanel {
                &::before {
                        background-color: $wcfHeaderMenuBackground;
+                       border-radius: 2px;
                        color: $wcfHeaderMenuLink;
                        font-family: FontAwesome;
                        font-size: 28px;
                        background-color: $wcfHeaderMenuLinkBackgroundActive;
                        color: $wcfHeaderMenuLinkActive;
                }
+               
+               &.pageMenuMobileButtonHasContent::before {
+                       animation: wcfMobileMenuNewContent 8s infinite;
+                       animation-delay: 2s;
+               }
        }
        
        .pageHeaderSearch:not(.open) {
index 354394ac5295b6260d9d0315a9494c4dc3053e1f..d83e552da04c4a89042d63aaca6b4835b040ce9d 100644 (file)
        }
 }
 
+.pageUserMenuMobile .menuOverlayItemBadge:last-child {
+       padding-right: 10px !important;
+}
+
 .menuOverlayItemLink.active,
 .menuOverlayItemLinkIcon.active {
        background-color: rgb(34, 49, 63);