From e7f1937c021f2ef4b366850a88946e2ca7c23c1a Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Thu, 23 Dec 2021 17:25:13 +0100 Subject: [PATCH] Indicator for user menu tabs with unread content --- ts/WoltLabSuite/Core/Ui/Page/Menu/User.ts | 14 ++++++++++++++ .../Core/Ui/User/Menu/Data/ModerationQueue.ts | 4 ++++ .../Core/Ui/User/Menu/Data/Notification.ts | 4 ++++ ts/WoltLabSuite/Core/Ui/User/Menu/Data/Provider.ts | 2 ++ .../js/WoltLabSuite/Core/Ui/Page/Menu/User.js | 13 +++++++++++++ .../Core/Ui/User/Menu/Data/ModerationQueue.js | 3 +++ .../Core/Ui/User/Menu/Data/Notification.js | 3 +++ wcfsetup/install/files/style/ui/pageMenu.scss | 12 ++++++++++++ 8 files changed, 55 insertions(+) diff --git a/ts/WoltLabSuite/Core/Ui/Page/Menu/User.ts b/ts/WoltLabSuite/Core/Ui/Page/Menu/User.ts index 76232a4bf8..6996a988a4 100644 --- a/ts/WoltLabSuite/Core/Ui/Page/Menu/User.ts +++ b/ts/WoltLabSuite/Core/Ui/Page/Menu/User.ts @@ -106,6 +106,7 @@ export class PageMenuUser implements PageMenuProvider { this.openNotifications(); } + this.refreshTabUnreadIndicators(); this.refreshUnreadIndicator(); } @@ -157,6 +158,8 @@ export class PageMenuUser implements PageMenuProvider { if (legacyPanel) { legacyPanel.close(); } + + this.refreshTabUnreadIndicators(); } private attachViewToPanel(tab: Tab): void { @@ -341,6 +344,7 @@ export class PageMenuUser implements PageMenuProvider { const tab = document.createElement("a"); tab.classList.add("pageMenuUserTab"); + tab.dataset.hasUnreadContent = "false"; tab.dataset.origin = data.origin; tab.id = tabId; tab.setAttribute("aria-controls", panelId); @@ -377,6 +381,16 @@ export class PageMenuUser implements PageMenuProvider { this.userMenu.classList.remove("pageMenuMobileButtonHasContent"); } } + + private refreshTabUnreadIndicators(): void { + this.userMenuProviders.forEach((provider, tab) => { + if (provider.hasUnreadContent()) { + tab.dataset.hasUnreadContent = "true"; + } else { + tab.dataset.hasUnreadContent = "false"; + } + }); + } } export function hasValidUserMenu(): boolean { diff --git a/ts/WoltLabSuite/Core/Ui/User/Menu/Data/ModerationQueue.ts b/ts/WoltLabSuite/Core/Ui/User/Menu/Data/ModerationQueue.ts index 6cca4beea7..15da627128 100644 --- a/ts/WoltLabSuite/Core/Ui/User/Menu/Data/ModerationQueue.ts +++ b/ts/WoltLabSuite/Core/Ui/User/Menu/Data/ModerationQueue.ts @@ -118,6 +118,10 @@ class UserMenuDataModerationQueue implements UserMenuProvider { return "com.woltlab.wcf.moderation"; } + hasUnreadContent(): boolean { + return this.counter > 0; + } + async markAsRead(objectId: number): Promise { const response = (await dboAction("markAsRead", "wcf\\data\\moderation\\queue\\ModerationQueueAction") .objectIds([objectId]) diff --git a/ts/WoltLabSuite/Core/Ui/User/Menu/Data/Notification.ts b/ts/WoltLabSuite/Core/Ui/User/Menu/Data/Notification.ts index 59d7e74c26..783e0e73c6 100644 --- a/ts/WoltLabSuite/Core/Ui/User/Menu/Data/Notification.ts +++ b/ts/WoltLabSuite/Core/Ui/User/Menu/Data/Notification.ts @@ -209,6 +209,10 @@ class UserMenuDataNotification implements UserMenuProvider { return this.options.noItems; } + hasUnreadContent(): boolean { + return this.counter > 0; + } + isStale(): boolean { if (this.stale) { return true; diff --git a/ts/WoltLabSuite/Core/Ui/User/Menu/Data/Provider.ts b/ts/WoltLabSuite/Core/Ui/User/Menu/Data/Provider.ts index c5a7e8495c..6df7eefe14 100644 --- a/ts/WoltLabSuite/Core/Ui/User/Menu/Data/Provider.ts +++ b/ts/WoltLabSuite/Core/Ui/User/Menu/Data/Provider.ts @@ -39,6 +39,8 @@ export interface UserMenuProvider { getView(): UserMenuView; + hasUnreadContent(): boolean; + isStale(): boolean; markAsRead(objectId: number): Promise; diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Menu/User.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Menu/User.js index 3813d01a83..5f49ae28da 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Menu/User.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Menu/User.js @@ -66,6 +66,7 @@ define(["require", "exports", "tslib", "./Container", "../../../Language", "../. else { this.openNotifications(); } + this.refreshTabUnreadIndicators(); this.refreshUnreadIndicator(); } openNotifications() { @@ -103,6 +104,7 @@ define(["require", "exports", "tslib", "./Container", "../../../Language", "../. if (legacyPanel) { legacyPanel.close(); } + this.refreshTabUnreadIndicators(); } attachViewToPanel(tab) { const origin = tab.dataset.origin; @@ -250,6 +252,7 @@ define(["require", "exports", "tslib", "./Container", "../../../Language", "../. const panelId = Util_1.default.getUniqueId(); const tab = document.createElement("a"); tab.classList.add("pageMenuUserTab"); + tab.dataset.hasUnreadContent = "false"; tab.dataset.origin = data.origin; tab.id = tabId; tab.setAttribute("aria-controls", panelId); @@ -281,6 +284,16 @@ define(["require", "exports", "tslib", "./Container", "../../../Language", "../. this.userMenu.classList.remove("pageMenuMobileButtonHasContent"); } } + refreshTabUnreadIndicators() { + this.userMenuProviders.forEach((provider, tab) => { + if (provider.hasUnreadContent()) { + tab.dataset.hasUnreadContent = "true"; + } + else { + tab.dataset.hasUnreadContent = "false"; + } + }); + } } exports.PageMenuUser = PageMenuUser; function hasValidUserMenu() { diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/User/Menu/Data/ModerationQueue.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/User/Menu/Data/ModerationQueue.js index 77f35a9933..761e67d653 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/User/Menu/Data/ModerationQueue.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/User/Menu/Data/ModerationQueue.js @@ -80,6 +80,9 @@ define(["require", "exports", "tslib", "../../../../Ajax", "../View", "../Manage getIdentifier() { return "com.woltlab.wcf.moderation"; } + hasUnreadContent() { + return this.counter > 0; + } async markAsRead(objectId) { const response = (await (0, Ajax_1.dboAction)("markAsRead", "wcf\\data\\moderation\\queue\\ModerationQueueAction") .objectIds([objectId]) diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/User/Menu/Data/Notification.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/User/Menu/Data/Notification.js index 4fd33066e7..4fd617593b 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/User/Menu/Data/Notification.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/User/Menu/Data/Notification.js @@ -155,6 +155,9 @@ define(["require", "exports", "tslib", "../../../../Ajax", "../View", "../Manage getEmptyViewMessage() { return this.options.noItems; } + hasUnreadContent() { + return this.counter > 0; + } isStale() { if (this.stale) { return true; diff --git a/wcfsetup/install/files/style/ui/pageMenu.scss b/wcfsetup/install/files/style/ui/pageMenu.scss index 554bfbf2d9..b0a274b8a2 100644 --- a/wcfsetup/install/files/style/ui/pageMenu.scss +++ b/wcfsetup/install/files/style/ui/pageMenu.scss @@ -174,6 +174,18 @@ &[aria-selected="true"] { background-color: var(--background-color-active); } + + &[aria-selected="false"][data-has-unread-content="true"]::after { + background-color: var(--color-indicator); + border-radius: 50%; + content: ""; + height: 10px; + opacity: 1; + position: absolute; + right: 5px; + top: 5px; + width: 10px; + } } .pageMenuUserTabPanel { -- 2.20.1